Python多重处理:结束无限计数器

Bix*_*ixx 3 python multiprocessing

我是多处理的新手,我只是想用Python 3.2编写一个简单的程序,该程序的一个计数器在一个线程中无限增加,而第二个线程检查第一个线程中是否已达到给定值。一旦达到该值,我希望关闭多处理线程,并使程序显示“ Process Complete”语句。

据我了解,该程序看起来像(给定值为10):

import multiprocessing as mp


def Counter():
    i=1
    while i > 0:
        print("i: ",i)
        i+=1


def ValueTester(i):
    if i >= 10:
        *End Counter Function Thread*


if __name__ == '__main__':

    *Begin multiprocessing, one thread for "Counter" and a second for "ValueTester"*

    print("Process Complete")
Run Code Online (Sandbox Code Playgroud)

我为伪代码的模糊性表示歉意。我已经阅读了Python文档以及几个不同的示例,但似乎找不到简单的解决方案。

另外,一旦这有效,我将如何设置给定的停止值(即,将变量传递给ValueTester,而不仅仅是使用10)?

非常感谢您的帮助。

unu*_*tbu 5

在这里,我们需要谨慎区分线程和进程。

所有线程都在同一进程下运行。可以在线程之间共享访问的值。只有当值受一个保护时,线程才能以安全(协调)的方式更改值。threading.Lock在更改之前。在CPython中,Python和PyPy都是最常见的实现,但是与Jython或Iron Python等其他实现相反,GIL(全局解释器锁)可防止在任何给定时间运行多个线程。因此,在CPython下,多个线程实际上是串行运行的,而不是并行运行的。尽管如此,多个线程对于I / O专心工作(例如查询许多网站)还是有用的,因为在那里大部分时间都花在等待网络(I / O)活动上。因此,与诸如数学计算之类的CPU密集型任务相比,多个线程不必等待那么多,就可以争取访问单个CPU。

综上所述,您正在处理多个进程,而不是线程。流程彼此独立。它们可以并且确实可以在多个CPU上并发运行(包括CPython下)。生成流程时,会将全局值从原始流程复制到生成的流程。在具有“写时复制”功能的某些OS(如Linux)上,值实际上是在进程之间共享的,直到某个进程试图覆盖某个值为止,此时该值将被复制以变得独立于其他进程。因此,当您修改值时,两个过程最终会得到两个名为相同但可以具有完全不同的值的变量

多处理模块提供了特殊的对象,以促进 进程之间的共享状态。这些措施包括mp.Valuemp.Arraymp.Manager。请注意,当您使用这些对象时,还必须使用amp.Lock 来防止一个进程更改值,而另一进程尝试执行相同的操作。但是,由于必须等待释放锁,因此该锁也会减慢进程。

现在,要在另一个过程中达到条件时向一个过程发出信号,请使用mp.Event

import multiprocessing as mp
import time

def Counter(i, event, lock):
    with lock:
        i.value = 1
    while i.value > 0 and not event.is_set():
        print("i: ", i.value)
        with lock:
            i.value += 1


def ValueTester(i, stopval, event):
    while True:
        if i.value >= stopval:
            event.set()
            break
        else:
            time.sleep(0.1)


if __name__ == '__main__':
    num = mp.Value('d', 0.0)
    # A lock is not absolutely necessary here since only one process modifies
    # num, but I'm including it since it is necessary (to avoid race conditions)
    # in the more usual case when multiple processes may modify num.
    lock = mp.Lock()
    event = mp.Event()
    counter = mp.Process(target=Counter, args=(num, event, lock))
    counter.start()
    tester = mp.Process(target=ValueTester, args=(num, 10, event))
    tester.start()
    tester.join()
    counter.join()
    print("Process Complete")
Run Code Online (Sandbox Code Playgroud)

有关如何使用多重处理的更多示例,请参见Doug Hellman的每周Python模块教程