我正在编写一个Python程序,该程序需要使用充当过滤器的外部unix程序来清理许多小字符串.当前,我为每个要清理的字符串创建一个新的子进程:
import subprocess
def cleanstring(s):
proc = subprocess.Popen(['/bin/filter','-n'],
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
out, err = proc.communicate(s)
assert not err
return out
显然,这种方法效率极低.在需要的时候,有什么有效的方法可以启动过滤器子进程并通过stdin / stdout与之通信?
我一直在研究使用Python Queues来实现这一点,但是对于这些来说,它们可能是一个过大的杀伤力.该代码将在非线程Web服务器上的Django视图中调用,因此它只会是单个线程多次调用.
谢谢!
解决方法:
如果您没有测量它,那么这不是性能问题,更不用说“严重无效”了.
也就是说,您可以与以下子流程进行通信:
import subprocess
import sys
p = subprocess.Popen('bc', shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for i in range(10):
p.stdin.write('%s*2\n' % (i,))
res = p.stdout.readline()
if res:
print "vtrip says %s*2 is %s" % (i, res.strip())
p.stdin.flush()
这将打印由同一bc进程返回的0-9的双精度数.应该易于适应detex(主要是正确处理齐平,以便一端不会卡住等待另一端).
那是沟通的一部分.至于“在Django内部长期运行”可能不是一个好主意.队列的确可能太多了.
像Celery等人这样的任务队列是用于独立处理任务的,而不是用于处理每个任务的相同长期运行的服务.
也许在侧面运行一些小的python守护程序,保持过滤器进程打开并处理Django的请求?我们是在谈论每天有100个用户的繁重负载还是内部负载?除了一些粗略的锁定之外,您可能不需要太多同步.