2017-02-25 22 views
1

ここでは、Python readline()を実験するために使用したコードを示します。空のファイルのようなオブジェクトのように、readlineが空のファイルをブロックしないのは本当ですか?

import threading, os, time 

def worker(): 
    file.seek(0) 
    print ("First attempt on file: " + file.readline().strip()) 
    print ("First attempt on pipe: " + Iget.readline().strip()) 
    print ("Second attempt on pipe: " + Iget.readline().strip()) 
    file.seek(0) 
    print ("Second attempt on file: " + file.readline().strip()) 
    print ("Third attempt on file: " + file.readline().strip()) 

fdIget, fdIset = os.pipe() 
Iget = os.fdopen(fdIget) 
Iset = os.fdopen(fdIset, 'w') 

file = open("Test.txt", "w+") 

t = threading.Thread(target=worker) 
t.start() 

time.sleep(2) 
Iset.write("Parent pipe\n") 
Iset.flush() 
file.write("Parent file.\n") 
file.flush() 

time.sleep(2) 
Iset.write("Again Parent pipe\n") 
Iset.flush() 
file.write("Again Parent file.\n") 
file.flush() 

t.join() 

出力は

First attempt on file: 
First attempt on pipe: Parent pipe 
Second attempt on pipe: Again Parent pipe 
Second attempt on file: Parent file. 
Third attempt on file: Again Parent file. 

であることはreadline()は空のファイルをブロックしないようです - ファイルが空であるため、おそらくそれは、EOFを見ています。一方、空のファイルのようなオブジェクトにはreadline()のブロックがあります。ファイルのようなオブジェクトを閉じるまで、EOFは見えません。私はそれが間違っていることを期待しています - 私は何か基本的なものを欠いています。ファイルのようなオブジェクトと同様に、ハンドルが閉じられた後でなければ、空のファイルにreadline()ブロックを持つ方がより均一になりました。

答えて

1

ファイルオブジェクトは、他の誰かがファイルに対してオープンハンドルを持っているかどうかわからないため、「ライターなしの空のファイル」から「空のファイルとライター」を区別することはできません。ファイルをクローズしているライターは、それを読み取っているハンドルには見えません。

これに対して、パイプは、その種の情報を通信します。パイプは、ライターがデータをリーダに通信するために明示的に閉じているストリームです。

ファイルがパイプのように動作する場合、ライターに関する情報が不足しているため、決して到着しない別のラインを待って、ラインを使い果たしたときにブロックされます。

基本的には基本的に異なる目的で使用されており、他のものとまったく同じように動作するとは思われません。

+0

私はあなたの答えに答えます。あなたは "はい"と言います。リーダーは空のファイルを決してブロックしません。ファイルの目的が何であるかというと、私は誰もそれを別のもののために決めることはできないと考えています。ファイルに他のハンドル(特定のカテゴリ内にあるもの)があるかどうかを、読者に知らせるために、OSが内部的にmutexを実装していれば、間違いはありません。たとえそれが空であっても、読者はブロックすることができます。いくつかのシナリオではこれまでどおりブロックすることができますが、これはパイプでも当てはまります。私が自分のディレクトリにファイルを作成した場合、私はいつでも簡単にブロックしないコンテキストを作成することができます。 –

+0

@ Dominic108:一般に、ファイルはこの目的のために意図されていません。まれなシナリオ(および必要に応じて他の方法で処理できるもの)をサポートするために、すべての*ファイル使用にオーバーヘッドを追加することはひどい考えです。大部分のプログラムは、読み込み専用にファイルを開きます(Pythonプログラムでは、メインメソッドが呼び出される前に数十個のDLL /共有オブジェクトとモジュールが開かれることに注意してください)。すべての人が "いいえ"を確認するだけのオーバーヘッドが増えれば、誰も現在これを書いているわけではありませんので、まれにケースを最適化しています。 – ShadowRanger

+0

この問題を理解するまでにはしばらく時間がかかりました。それは基本的なものですが、あまり明らかではありません。もし読者がOSに問い合わせることを望んでいるならば、彼はファイルをループするかもしれない。だから、読者はミューテックスのようなものをブロックする必要がある。これはPythonレベルで行うことができます。ブロッキングストリームとして管理する必要があるファイルは、分離することができます。ファイルを所有するアプリケーションは、ストリームとして管理するかどうかを決定します。これは他のPythonアプリケーションにとっては透過的です。私の主張は、ファイルが空のときにブロックされることが必ずしも悪い設計であるとは思わないということです。 –

関連する問題