多处理python工作正常,但预期工作不好

多处理python工作正常,但预期工作不好,python,windows,multiprocessing,spyder,Python,Windows,Multiprocessing,Spyder,代码如下: from time import sleep from random import random from multiprocessing import Process def f(): for i in range(5): print("hola" , i) sleep(random()) if __name__ == "__main__": p = Process(target=f) q = Process(targe

代码如下:

from time import sleep
from random import random

from multiprocessing import Process

def f():
    for i in range(5):
        print("hola" , i)
        sleep(random())

if __name__ == "__main__":
    p = Process(target=f)
    q = Process(target=f)
    p.start()
    q.start()
    print("fin")
    ## sleep(1000)
这是我经常得到的结果:

但是代码中没有任何东西可以防止两个进程混合,那么为什么它们不混合呢


Windows 8,Python 2.7,使用anaconda最新版本的spyder

我要冒险说它是Windows:刚刚在Mac OS x Yosemite上运行了Python 2.7.10的示例,我得到了一个更符合预期的结果:

In [27]: def f():
   ....:         for i in range(5):
   ....:                 print("hola" , i)
   ....:                 sleep(random())
   ....:         

In [28]: if __name__ == "__main__":
   ....:         p = Process(target=f)
   ....:         q = Process(target=f)
   ....:         p.start()
   ....:         q.start()
   ....:         print("fin")
   ....:     
fin

In [29]: ('hola', 0)
('hola', 0)
('hola', 1)
('hola', 2)
('hola', 1)
('hola', 3)
('hola', 4)
('hola', 2)
('hola', 3)
('hola', 4)
看看这是否有帮助:

我要冒险说这是Windows:在Mac OS x Yosemite上运行Python 2.7.10上的示例,我得到了一个更符合预期的结果:

In [27]: def f():
   ....:         for i in range(5):
   ....:                 print("hola" , i)
   ....:                 sleep(random())
   ....:         

In [28]: if __name__ == "__main__":
   ....:         p = Process(target=f)
   ....:         q = Process(target=f)
   ....:         p.start()
   ....:         q.start()
   ....:         print("fin")
   ....:     
fin

In [29]: ('hola', 0)
('hola', 0)
('hola', 1)
('hola', 2)
('hola', 1)
('hola', 3)
('hola', 4)
('hola', 2)
('hola', 3)
('hola', 4)
看看这是否有帮助:

您可以一个接一个地启动它们。这可能就是原因。@Creator我真的不理解这个评论,对不起,我不确定Python是如何工作的,但这可能与您先调用p.start,然后调用q.start有关。这与Windows无关。Spyder必须将过程标准输出设置为管道。由于
sys.stdout
不是交互式的(即tty或console),Python使用缓冲i/O。在每个进程退出之前,您没有写入足够的数据以便在任一子进程中刷新缓冲区。您可以使用
python test.py | more
从命令行复制此命令。您可以设置环境变量
pythonunbuffer=1
以强制python使用无缓冲标准I/O。但是请注意,这实际上会在python 2.x中导致与Windows相关的问题,因为它还将
stdin
切换为二进制模式不是将
\r\n
转换为
\n
。而是一个接一个地启动它们。这可能就是原因。@Creator我真的不理解这个评论,对不起,我不确定Python是如何工作的,但这可能与您先调用p.start,然后调用q.start有关。这与Windows无关。Spyder必须将过程标准输出设置为管道。由于
sys.stdout
不是交互式的(即tty或console),Python使用缓冲i/O。在每个进程退出之前,您没有写入足够的数据以便在任一子进程中刷新缓冲区。您可以使用
python test.py | more
从命令行复制此命令。您可以设置环境变量
pythonunbuffer=1
以强制python使用无缓冲标准I/O。但是请注意,这实际上会在python 2.x中导致与Windows相关的问题,因为它还将
stdin
切换为二进制模式不是将
\r\n
翻译成
\n
。感谢您尝试了这些代码,我们在教室里使用Ubuntu,所以我已经怀疑这一点,因为我的笔记本电脑只有这个“问题”,但我需要能够在笔记本电脑上工作:(尝试随机扩展你的长度(乘以10,看看会发生什么。)你也可以尝试在f中导入random,看看会发生什么。每当你有这种奇怪的行为时,很容易在Python中进行实验,看看发生了什么。我之前应该说过,输出是按块打印的,而不是按行打印的。所以使用random()*10,我得到了相同的输出(按块打印)但是尝试代码只需要更长的时间,我们在教室里使用Ubuntu,所以我已经开始怀疑这一点,因为我的笔记本电脑只有这个“问题”,但我需要能够在笔记本电脑上工作:(尝试随机延长你的长度(乘以10,看看会发生什么。)你也可以尝试在f中导入random,看看会发生什么。每当你有这种奇怪的行为时,很容易在Python中进行实验,看看发生了什么。我之前应该说过,输出是按块打印的,而不是按行打印的。所以使用random()*10,我得到了相同的输出(按块打印)但这只需要更长的时间