Python 多处理信号量不工作

标签 python multithreading multiprocessing semaphore

我希望我的程序一次打印一行,但它一次打印多行并造成乱码。我似乎无法找出为什么信号量没有阻止多个进程相互打印。

我怎样才能让它尊重信号量?

这是我的代码的简化版本,它在运行时遇到了同样的问题(我在 Windows 上运行 Python 2.7.11(无法更改)):

import multiprocessing

rightofway = multiprocessing.Semaphore(1)

def writenum(number):
    rightofway.acquire()
    print("[+] - " + str(number))
    rightofway.release()
    return

def main():
    starting = 0
    ending = 50

    list = range(starting, ending)

    pool = multiprocessing.Pool(10)
    pool.map(writenum, list)
    return

#Required for Windows multiprocessing
if __name__ == '__main__':
    main()

这是一个乱码输出的例子:

[+] - 0
[+] - 1
[+] - 2
[+] - 3
[+] - 4
[+] - 5
[+] - 6
[+] - 7
[[+] - 8
+] - 10[
+] - 9[+] - 11
[+] - 12

[[+] - 13+] - 14

[[+] - 15+] - 16

[[+] - 18+] - 17

[[+] - 19+] - 20

[[+] - 22+] - 21

[[+] - 23+] - 24

[[+] - 26+] - 25

[[+] - 27+] - 28

[[+] - 30+] - 29

[[+] - 31+] - 32

[[+] - 34+] - 33

[[+] - 35+] - 36

[[+] - 38+] - 37

[[+] - 39+] - 40

[[+] - 42+] - 41

[[+] - 43+] - 44

[[+] - 46+] - 45

[[+] - 47+] - 48

[+] - 49

这是我想要的输出示例(注意我不关心顺序):

[+] - 0
[+] - 1
[+] - 2
[+] - 3
[+] - 4
[+] - 5
[+] - 6
[+] - 7
[+] - 8
[+] - 9
[+] - 10
[+] - 11
[+] - 12
[+] - 13
[+] - 14
[+] - 15
[+] - 16
[+] - 17
[+] - 18
[+] - 19
[+] - 20
[+] - 21
[+] - 22
[+] - 23
[+] - 24
[+] - 25
[+] - 26
[+] - 27
[+] - 28
[+] - 29
[+] - 30
[+] - 31
[+] - 32
[+] - 33
[+] - 36
[+] - 34
[+] - 35
[+] - 37
[+] - 38
[+] - 40
[+] - 39
[+] - 41
[+] - 42
[+] - 44
[+] - 43
[+] - 45
[+] - 46
[+] - 48
[+] - 47
[+] - 49

最佳答案

你的问题类似于this one .

来自多处理编程指南。

Explicitly pass resources to child processes

... it is better to pass the object as an argument to the constructor for the child process.

Apart from making the code (potentially) compatible with Windows ...

在 Windows 上,您需要将共享对象传递给 Process 构造函数参数列表。否则,子进程将获得一个全新的副本,而不是父进程的副本。这就是为什么您会觉得 Semaphore 不工作的原因。这两个进程正在创建自己不同的 Semaphore 对象,而不是共享同一个对象。

要将 Semaphore 对象传递给 Windows 上的 Pool,您需要费点功夫,但不要太多。由于您不能将Semaphore 对象直接传递给writenum 函数,您需要依赖于Pool initializer

from multiprocessing import Semaphore, Pool

mutex = None

def initializer(semaphore):
    """This function is run at the Pool startup. 
    Use it to set your Semaphore object in the child process.

    """
    global mutex

    mutex = semaphore

def writenum(args):
    with mutex:
        print "[+] - " + str(number)

def main():
    semaphore = Semaphore()
    pool = Pool(initializer=initializer, initargs=[semaphore])

    numbers = range(50)

    pool.map(writenum, numbers)

编辑:刚注意到我写的是Lock 而不是Semaphore。核心推理保持不变。

关于Python 多处理信号量不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50379009/

相关文章:

Python更改文件名的一部分

python - Cython hello world 示例在 Windows 上不起作用

c++ - for循环内的多线程 - OpenMP

Python - 多进程,类的成员函数

python - 如何从 RegEx(正则表达式)生成所有组合?

python - ModuleNotFoundError : No module named 'requests' in PyCharm

java - 鉴于 jdk1.6 及更高版本中的 HashMaps 导致多线程问题,我应该如何修复我的代码

java - 我是否在 EDT 之外更新 Swing 组件?

python - 在 Python 中划分大文件以进行多处理的最佳方法是什么?

python - 创建时与命名空间的Python多处理池交互