了解os.fork和Queue.Queue

时间:2012-03-29 20:42:12

标签: python multithreading queue fork

我想使用并行执行来实现一个简单的python程序。它是I / O绑定的,所以我认为线程是合适的(而不是进程)。在阅读了Queue和fork的文档之后,我认为以下内容可能有用。

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方法不会做同样的事情。我错过了什么?

3 个答案:

答案 0 :(得分:7)

POSIX fork系统调用在同一个地址空间内创建一个新的进程,而不是新的线程

  

fork()函数应创建一个新进程。新的过程(孩子   process)应该是调用进程的精确副本(父进程)   过程),除非详述如下:[...]

所以Queue在你的第一个例子中重复,而不是在父母和孩子之间共享。

您可以使用multiprocessing.Queue代替,或者只使用第二个示例中的主题:)

顺便说一下,仅出于副作用isn't good practice使用列表推导有几个原因。您应该使用for循环代替:

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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