使用管道时 open() 与 os.open() 的行为
Behaviour of open() vs os.open() when using pipes
我一直在为写作和阅读管道而苦苦挣扎。问题是,一方面我通过 open()
获得的文件对象处理管道。另一方面,我使用的是 "low-level" os.open()
获得的文件描述符。虽然看起来很相似,但代码的行为却大不相同,我真的不明白为什么。
我举了一个小例子。我正在改变写入 pipe.In write_1.py 的方法,我使用 os.open()
并且一切都按预期工作。在 write_2.py 中使用 open()
,当从管道读取时我得到一个 EAGAIN-error 并且只有在书写端最后用pipe.close()
关闭了。
两种情况的阅读方式相同,参见read.py。
你能解释一下不同的行为吗?
(Python 版本 3.5.2)
文件
# write_1.py
import os
import errno
import time
bufferSize = 100
PATH = "pipe"
i = 0
pipe = os.open(PATH, os.O_WRONLY | os.O_NONBLOCK)
while i < 20:
i +=1
my_str = "written {0}-times".format(i)
try:
input = os.write(pipe, my_str.encode())
except OSError as err:
if err.errno == 11:
print("error 11")
continue
else:
raise err
if input:
print("written {0} chars ".format(input))
print("Sleep 500 ms")
time.sleep(0.5)
os.close(pipe)
# write_2.py
import os
import errno
import time
bufferSize = 100
PATH = "pipe"
i = 0
pipe = open(PATH, "w")
fd = pipe.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
while i < 20:
i +=1
my_str = "written {0}-times".format(i)
try:
input = pipe.write(my_str)
except OSError as err:
if err.errno == 11:
print("error 11")
continue
else:
raise err
if input:
print("written {0} chars ".format(input))
print("Sleep 500 ms")
time.sleep(0.5)
pipe.close()
# read.py
import os
import errno
import time
bufferSize = 100
PATH = "pipe"
i = 0
pipe = os.open(PATH, os.O_RDONLY | os.O_NONBLOCK)
while i < 100:
i +=1
try:
input = os.read(pipe, bufferSize)
except OSError as err:
if err.errno == 11:
print("error 11")
print("Sleep 500 ms")
time.sleep(0.5)
continue
else:
raise err
if input:
print(input)
print("Sleep 500 ms")
time.sleep(0.5)
os.close(pipe)
使用 open
,您已接受默认缓冲设置(通过不提供 buffering
参数),因此您将获得一个缓冲文件对象。此缓冲区独立于任何 OS 级缓冲。
使用 os.open
,没有文件对象,也没有文件对象级缓冲。
(此外,您使用 open
在阻塞 I/O 模式下打开管道,但这不是造成您所看到的差异的原因。)
我一直在为写作和阅读管道而苦苦挣扎。问题是,一方面我通过 open()
获得的文件对象处理管道。另一方面,我使用的是 "low-level" os.open()
获得的文件描述符。虽然看起来很相似,但代码的行为却大不相同,我真的不明白为什么。
我举了一个小例子。我正在改变写入 pipe.In write_1.py 的方法,我使用 os.open()
并且一切都按预期工作。在 write_2.py 中使用 open()
,当从管道读取时我得到一个 EAGAIN-error 并且只有在书写端最后用pipe.close()
关闭了。
两种情况的阅读方式相同,参见read.py。 你能解释一下不同的行为吗?
(Python 版本 3.5.2)
文件
# write_1.py
import os
import errno
import time
bufferSize = 100
PATH = "pipe"
i = 0
pipe = os.open(PATH, os.O_WRONLY | os.O_NONBLOCK)
while i < 20:
i +=1
my_str = "written {0}-times".format(i)
try:
input = os.write(pipe, my_str.encode())
except OSError as err:
if err.errno == 11:
print("error 11")
continue
else:
raise err
if input:
print("written {0} chars ".format(input))
print("Sleep 500 ms")
time.sleep(0.5)
os.close(pipe)
# write_2.py
import os
import errno
import time
bufferSize = 100
PATH = "pipe"
i = 0
pipe = open(PATH, "w")
fd = pipe.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
while i < 20:
i +=1
my_str = "written {0}-times".format(i)
try:
input = pipe.write(my_str)
except OSError as err:
if err.errno == 11:
print("error 11")
continue
else:
raise err
if input:
print("written {0} chars ".format(input))
print("Sleep 500 ms")
time.sleep(0.5)
pipe.close()
# read.py
import os
import errno
import time
bufferSize = 100
PATH = "pipe"
i = 0
pipe = os.open(PATH, os.O_RDONLY | os.O_NONBLOCK)
while i < 100:
i +=1
try:
input = os.read(pipe, bufferSize)
except OSError as err:
if err.errno == 11:
print("error 11")
print("Sleep 500 ms")
time.sleep(0.5)
continue
else:
raise err
if input:
print(input)
print("Sleep 500 ms")
time.sleep(0.5)
os.close(pipe)
使用 open
,您已接受默认缓冲设置(通过不提供 buffering
参数),因此您将获得一个缓冲文件对象。此缓冲区独立于任何 OS 级缓冲。
使用 os.open
,没有文件对象,也没有文件对象级缓冲。
(此外,您使用 open
在阻塞 I/O 模式下打开管道,但这不是造成您所看到的差异的原因。)