python 多处理 class

python multiprocessing class

我用这段代码遇到了奇怪的 python 行为:

#!/usr/bin/python

import multiprocessing
import time
import sys

class worker(multiprocessing.Process):

    def __init__(self, val):
        super(worker,self).__init__()
        self.val = val

    def update_val(self,val):
        self.val = val
        print("self.val now is %s" %(self.val))

    def run(self):
        while True:
            print("Worker report: val is %s" % (self.val))
            time.sleep(self.val)


subproc = worker(10)
subproc.start()
while True:
    new_val =  sys.stdin.readline().rstrip()
    if new_val:
        subproc.update_val(new_val)
    print("Main report: val is %s" % (subproc.val))

我希望,对象 subproc 中的变量 val 已被 update_val 函数更改。 但我很惊讶,因为该变量仅针对来自 main 进程的查询进行了更改。 函数 run 仍然使用旧值:

$ ./test.py
Worker report: val is 10
Worker report: val is 10
5
self.val now is 5
Main report: val is 5

Main report: val is 5
Worker report: val is 10
Worker report: val is 10

问题的原因可能是什么?此代码在 Python2.7Python3.6 中的工作方式类似。提前致谢!

Multiprocessing 生成一个 new 进程,复制您所在的当前进程(及其内存状态),因此您无法从当前进程访问该新进程,您应该进行通信他们这样做。

查看进程之间的 sharing state or exchanging objects

工作代码:

#!/usr/bin/python
import multiprocessing
import time
import sys

class worker(multiprocessing.Process):

    def __init__(self, valobj):
        super(worker,self).__init__()
        self.val = valobj

    def run(self):
        while True:
            print("Worker report: val is %s" % (self.val.value))
            time.sleep(self.val.value)


valobj = multiprocessing.Value('i', 5)
subproc = worker(valobj)
subproc.start()
while True:
    new_val =  sys.stdin.readline().rstrip()
    if new_val:
        valobj.value = int(new_val)
    print("Main report: val is %s" %(valobj.value))

此代码具有所需的行为:

$ ./test.py
Worker report: val is 5
1
Main report: val is 1

Main report: val is 1

Main report: val is 1
Worker report: val is 1
Worker report: val is 1
Worker report: val is 1
3
Main report: val is 3
Worker report: val is 3
Worker report: val is 3

如果您可以使用 threading 而不是 multiprocessing,请尝试以下代码。 我只是将 multiprocessing 更改为 threading 并将线程对象的 daemon 属性设置为 True.

daemon

boolean value indicating whether this thread is a daemon thread (True) or not (False). This must be set before start() is called, otherwise RuntimeError is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to daemon = False.

The entire Python program exits when no alive non-daemon threads are left.

简而言之,如果你的worker thread设置为daemon=True并且main thread退出,worker thread也会退出,因为没有non-daemon thread活着(main thread 必须是 non-daemon thread)。

您可以简单地通过KeyboardInterrupt(Ctrl+c)退出整个程序。

import threading
import time
import sys


class worker(threading.Thread):

    def __init__(self, val):
        super(worker, self).__init__()
        self.val = val

    def update_val(self, val):
        if val.isdigit():
            self.val = int(val)
            print("self.val now is %s" % (self.val))
        else:
            print("val should be digit")

    def run(self):
        while True:
            print("Worker report: val is %s" % (self.val))
            time.sleep(self.val)


subproc = worker(10)
subproc.daemon = True    # By setting daemon, the threading will be killed when main thread exit.
subproc.start()
while True:
    new_val = sys.stdin.readline().rstrip()
    if new_val:
        subproc.update_val(new_val)
    print("Main report: val is %s" % (subproc.val))