python的匿名管道爆了怎么办
python的匿名管道爆了怎么办
起因
最近使⽤了python的匿名管道,⼤体上就是python使⽤了subproces.Popen()起了⼀个⼦进程,主进程与⼦进程使⽤匿名管道进⾏通讯,⼤体代码如下。
# 主进程
import subprocess
from subprocess import PIPE
p = subprocess.Popen("python3 run.py", shell=False, stdin=PIPE, stdout = PIPE)
tmp_list = ["jfkdslakfjdslkfj\n", "ienwfjewnufwen\n".......]这⾥模拟⼀⼤堆输⼊
for item in tmp_list:
p.stdin.de())
p.stdin.flush()
本来这其实是⼀段再正常不过的代码,只要我输⼊⼀条他读⼀条就没问题,但是写⼦进程那个狗⽇的,他不按照我的输⼊输出规矩⾏事,管道⾥⾯打进去了数据,他⼀点也不急,他偏要⾃⼰需要多少就拿多少,我不停的输⼊,他就看情况拿,这个直接导致了我的管道跑满爆炸。。。他的程序我就不po了,你只要记得他⼀直没有input()就⾏。⼤概这个样⼦
# ⼦进程
import subprocess
from subprocess import PIPE
tmp_list = ["jfkdslakfjdslkfj\n", "ienwfjewnufwen\n".......]这⾥模拟⼀⼤堆输⼊
for item in tmp_list:
pass    #⽼⼦就是不⼲任何事情
input() #有事情,⽼⼦读⼀⾏
.
..
input()#⼜有事情,⽼⼦再读⼀⾏
然后管道越积越多,就爆炸了。。卡在了stdin.write上⾯。
问题就在于我怎么增⼤管道⼤⼩
ulimit -a可以查看管道的⼤⼩但是没有卵⽤,这个是管道⼤⼩,撑爆的是buffer
修改proc/sys/fs/pipe-max-size中的值,发现是1048576也就是⼤概10M,⽽⼀般管道⼤⼩是64kB,说明我们还是存在增⼤空间的查阅了⼀下⽅法,发现c语⾔使⽤fcntl修改F_SETPIPE_SZ可以更改当前描述符匿名管道的⼤⼩。但我⽤的是python,有fcntl,但是⾥⾯没有F_SETPIPE_SZpython怎么读的
多⽅尝试,终于到,没有F_SETPIPE_SZ就⾃⼰定义⼀个,⾄于⾥⾯怎么做,我也没有查很清楚,希望⾼⼿帮我解答。
最后代码如下
# 主进程
import subprocess
import fcntl
from subprocess import PIPE
p = subprocess.Popen("python3 run.py", shell=False, stdin=PIPE, stdout = PIPE)
fcntl.F_SETPIPE_SZ = 1031
fcntl.fcntl(fd, fcntl.F_SETPIPE_SZ, 1048576)
tmp_list = ["jfkdslakfjdslkfj\n", "ienwfjewnufwen\n".......]这⾥模拟⼀⼤堆输⼊
for item in tmp_list:
p.stdin.de())
p.stdin.flush()
fcntl.F_SETPIPE_SZ = 1031是⾃定义的⼀个值,1031应该代表管道⼤⼩,不⽤担⼼python没有,最终系统⾥⼀定是有的
这种⽅式管道可以容纳⼤概10MB的输⼊,很多情况下够了。但是⾥⾯具体的原理还是望⾼⼿们帮我解答