2012-03-29 57 views
6

我想用并行执行来实现一个简单的python程序。它是I/O绑定的,所以我认为线程是合适的(与流程相反)。在阅读Queue和fork的文档后,我认为类似下面的内容可能会起作用。了解os.fork和Queue.Queue

q = Queue.Queue() 

if os.fork():   # child 
    while True: 
     print q.get() 
else:     # parent 
    [q.put(x) for x in range(10)] 

但是,get()调用永远不会返回。我认为一旦其他线程执行put()调用就会返回。使用线程模块,事情表现得更像我所料:

q = Queue.Queue() 

def consume(q): 
    while True: 
     print q.get() 

worker = threading.Thread (target=consume, args=(q,)) 
worker.start() 

[q.put(x) for x in range(10)] 

我只是不明白为什么fork方法不会做同样的事情。我错过了什么?

回答

7

的POSIX fork系统调用创建一个新的过程,而不是一个新的线程相同的寻址空间内:

叉()函数将创建一个新的进程。 [...]

所以Queue是你的第一个例子复制的,而不是:新进程(子 过程)应除详细如下是调用进程(父 过程)的精确副本在父母和孩子之间分享。

您可以使用multiprocessing.Queue代替或只是在你的第二个例子:)

顺便说使用线程一样,通过遍历的只是副作用isn't good practice有几个原因。您应该使用for循环代替:

for x in range(10): q.put(x) 
+1

提及'multiprocessing'的+1。 – 2012-03-29 21:04:16

0

叉子创建一个新过程。子进程和父进程不共享相同的队列:这就是为什么父进程放置的元素不能被子进程检索的原因。

1

要在不相关进程之间共享数据,可以使用命名管道。通过os.open()函数.. http://docs.python.org/2/library/os.html#os.open。您可以简单地将管道命名为named_pipe ='my_pipe',并在不同的python程序中使用os.open(named_pipe,),其中模式为WRONLY等。之后,您将创建一个FIFO以写入管道。不要忘了关闭管道和捕捉异常。