Python多处理信号量不工作

2024-06-12 05:13:44 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望我的程序一次打印一行,但是它一次打印多行,造成混乱。我似乎不明白为什么信号量没有阻止多个进程相互打印。在

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

下面是我的代码的一个简化版本,在运行时也有同样的问题(我运行的是带有python2.7.11的Windows(不能更改)):

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()

以下是乱输出的示例:

^{pr2}$

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

[+] - 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

Tags: 程序示例numberreturnmainwindowsdefending
2条回答

你的问题类似于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上,需要将共享对象传递给进程构造函数参数列表。否则,子进程将获得一个全新的副本,而不是父进程的副本。这就是为什么你会觉得Semaphore不起作用。这两个进程正在创建各自不同的Semaphore对象,而不是共享同一个对象。在

在Windows上,要将一个Semaphore对象传递给Pool,您需要一点努力,但不要太多。由于不能将Semaphore对象直接传递给writenum函数,因此需要依赖Poolinitializer。在

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,而不是{}。核心推理仍然是一样的。在

为了让事情简单一点,下面的工作对我很有效。在Win10上测试。 TL;DR-使用锁而不是信号量

import multiprocessing

rightofway = multiprocessing.Lock()

def writenum(number):

    with rightofway:
        print("[+] - " + str(number))

    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()

相关问题 更多 >