Python多处理无法正常工作

时间:2014-07-25 22:16:45

标签: python multithreading multiprocessing

我读过你可以用同样的方式使用多处理和多线程。我已尝试使用多线程执行此操作,但它不支持多处理。

我正在运行以下代码:

import multiprocessing
import time


test_list = []


def user_input():
    while True:
        number = raw_input('Please input a number: ')
        test_list.append(number)


def print_func():
    while True:
        for t in test_list:
            print t

        time.sleep(5)


if __name__ == '__main__':
    ui = multiprocessing.Process(target=user_input)
    p = multiprocessing.Process(target=print_func)

    ui.start()
    p.start()

我收到此程序的以下错误:

Traceback (most recent call last):
  File "C:\Python27\lib\multiprocessing\process.py", line 258, in _bootstrap
    self.run()
  File "C:\Python27\lib\multiprocessing\process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\Victor\Dropbox\Private\multiFile\main.py", line 10, in user_input
    number = raw_input('Please input a number: ')
EOFError: EOF when reading a line

1 个答案:

答案 0 :(得分:3)

  

我已经读到你可以用同样的方式使用多处理和多线程。

到某一点,是的。但是你超越了这一点。


第一个问题是,默认情况下,子进程不会获得stdio。这在Programming guidelines

中有解释
  

最初无条件地称为多处理:

os.close(sys.stdin.fileno())
  multiprocessing.Process._bootstrap()方法中的

- 这导致了进程中的进程问题。这已改为:

sys.stdin.close()
sys.stdin = open(os.devnull)

部分原因是,在这样的多个流程中共享stdio管道是危险的,也很困难。你想要做的是在父进程中分离stdin,然后显式地将原始stdin传递给你想要接管的任何一个孩子。


第二个问题是您尝试在进程之间共享全局变量test_list

正如Windows的编程指南一节所述:

  

全局变量

     

请记住,如果在子进程中运行的代码尝试访问全局变量,那么它看到的值(如果有的话)可能与Process.start时父进程中的值不同。调用。

换句话说,每个子进程都有自己的test_list副本,完全相互独立。您在user_input流程中所做的更改将不会显示在print_func流程中。

最重要的是,即使使用线程,您的代码也不是很安全。如果在线程(或进程)之间共享可变对象,则需要锁定它们。 (是的,在许多情况下,当使用内置类型时,在CPython上,GIL恰好让你安全,但是你可以准确地了解何时可以安全地逃脱它以及如何调试东西当你弄错了,或者你可以学习如何正确锁定东西。)

那么, 如何在进程之间共享状态?好吧,在解释它的文档中有一个名为Sharing state between processes的整个部分。但它通常不容易或有趣。这就是为什么该部分开始于:

  

如上所述,在进行并发编程时,通常最好尽量避免使用共享状态。使用多个流程时尤其如此。

更好的解决方案是传递消息而不是共享状态。这是Exchanging objects between processes中的几个部分的描述,对于大多数用例而言,它更简单。