Dalam gaya khas UNIX, read(2)
mengembalikan 0 byte untuk menunjukkan akhir file yang dapat berarti:
- Tidak ada lagi byte dalam file
- Ujung soket yang lain telah mematikan koneksi
- Penulis telah menutup pipa
Dalam kasus Anda, fifo.read()
mengembalikan string kosong, karena penulis telah menutup deskriptor filenya.
Anda harus mendeteksi kasus itu dan keluar dari lingkaran Anda:
reader.py :
import os
import errno
FIFO = 'mypipe'
try:
os.mkfifo(FIFO)
except OSError as oe:
if oe.errno != errno.EEXIST:
raise
print("Opening FIFO...")
with open(FIFO) as fifo:
print("FIFO opened")
while True:
data = fifo.read()
if len(data) == 0:
print("Writer closed")
break
print('Read: "{0}"'.format(data))
Sesi contoh
Terminal 1 :
$ python reader.py
Opening FIFO...
<blocks>
Terminal 2 :
$ echo -n 'hello' > mypipe
Terminal 1 :
FIFO opened
Read: "hello"
Writer closed
$
Perbarui 1 - Buka kembali terus-menerus
Anda menunjukkan bahwa Anda ingin terus mendengarkan tulisan di pipa, mungkin bahkan setelah penulis tutup.
Untuk melakukan ini secara efisien, Anda dapat (dan harus) memanfaatkan fakta bahwa
Biasanya, membuka blok FIFO hingga ujung lainnya juga terbuka.
Di sini, saya menambahkan loop lain di sekitar open
dan read
lingkaran. Dengan cara ini, setelah pipa ditutup, kode akan mencoba membukanya kembali, yang akan memblokir hingga penulis lain membuka pipa:
import os
import errno
FIFO = 'mypipe'
try:
os.mkfifo(FIFO)
except OSError as oe:
if oe.errno != errno.EEXIST:
raise
while True:
print("Opening FIFO...")
with open(FIFO) as fifo:
print("FIFO opened")
while True:
data = fifo.read()
if len(data) == 0:
print("Writer closed")
break
print('Read: "{0}"'.format(data))
Terminal 1 :
$ python reader.py
Opening FIFO...
<blocks>
Terminal 2 :
$ echo -n 'hello' > mypipe
Terminal 1 :
FIFO opened
Read: "hello"
Writer closed
Opening FIFO...
<blocks>
Terminal 2 :
$ echo -n 'hello' > mypipe
Terminal 1 :
FIFO opened
Read: "hello"
Writer closed
Opening FIFO...
<blocks>
... dan seterusnya.
Anda dapat mempelajari lebih lanjut dengan membaca man
halaman untuk pipa:
- PIPE(7) - Panduan Pemrogram Linux
- FIFO(7) - Panduan Pemrogram Linux
(Bertahun-tahun kemudian) Jika saya memahami kasus penggunaan OP menggunakan for ... in ...
melakukan apa yang diinginkan:
import os
FIFO = 'myfifo'
os.mkfifo(FIFO)
with open(FIFO) as fifo:
for line in fifo:
print(line)
Program ini dengan sabar menunggu input dari fifo hingga tersedia, lalu mencetaknya di layar. Sementara itu, tidak ada CPU yang digunakan.
Ini juga cara yang lebih idiomatis di Python, jadi saya akan merekomendasikannya daripada menggunakan read() secara langsung.
Jika sisi klien menulis ke fifo ditutup, for loop berakhir dan program berhenti. Jika Anda ingin membuka kembali fifo untuk menunggu klien berikutnya membukanya, Anda dapat meletakkan for
bagian menjadi while loop:
import os
FIFO = 'myfifo'
os.mkfifo(FIFO)
while True:
with open(FIFO) as fifo:
for line in fifo:
print(line)
Ini akan membuka kembali fifo dan menunggu seperti biasa.