命名管道占用100%CPU
我用 ./file.py < pipe >> logfile
来启动这个脚本,脚本内容是:
while True:
try:
I = raw_input().strip().split()
except EOFError:
continue
doSomething()
我该如何更好地处理命名管道?这个脚本总是占用100%的CPU,而且需要实时运行,所以我不能使用 time.sleep
。
2 个回答
所谓“实时”,其实是指“软实时”,因为你有多个进程在同时运行,并不是“硬实时”!这并不意味着你不能使用time.sleep
:即使是很短的暂停,也能让事情变得稍微好一些——试着在你的循环里加上time.sleep(0.01)
,这样可以给其他进程更多的机会去运行。如果不暂停,可能反而会让你花更长的时间,因为其他进程几乎没有机会来处理数据!
除此之外,@S.Lott说得很对:如果想要“实时”表现,你需要直接从sys.stdin
读取数据(不过根据平台的不同,可能不需要每次读取一个字节:通常sys.stdin.read(1024)
可以读取最多1024个字节,当sys.stdin
是一个管道或其他“原始”而不是“处理过的”文件描述符时,它会返回管道里有多少字节,如果少于100,就不会等待——你可以把文件描述符设置为非阻塞,这样可以确保这一点),然后在代码的后面进行字符串处理(比如把行连接起来、去掉空格等等)。
在遇到文件结束符(EOF)时,你会一直循环,反复得到EOF。EOF之后就不会再有输入了。
EOF并不是数据中的“空白”。它的意思是你连接的那个套接字已经断开,不能再用了。
如果你想要“实时”的数据,你需要从套接字中逐个读取字节,直到你得到一条完整的“消息”。比如一条消息可能以'\n'
结束。你不能使用raw_input
。
你需要使用sys.stdin.read(1)
来获取字节。
顺便说一下,管道是有缓冲的。所以你不会得到任何实时的数据。如果你想要“实时”的数据,你必须使用UDP套接字,而不是TCP管道。