multiprocessing.Process的实例在start后如何在外部调用实例方法改变实例的属性?

新手上路,请多包涵

先贴代码

# -*- coding: utf8 -*-
import multiprocessing
from threading import Timer
import time

class Process(multiprocessing.Process):
    def __init__(self):
        super().__init__()
        self._active = True

    def run(self):
        self.action()

    def pause(self):
        print("paused")
        self._active = False

    def action(self):
        while self._active :
            print(self._active)
            time.sleep(0.5)
        print(self._active)

p = Process()
timer = Timer(2, p.pause)
timer.start()
#p.pause()
p.start()

运行结果:

True
True
True
True
paused
True
True
True
True
True
...

在尝试实现对一个Process进行暂停操作的时候遇到了这样一个问题。我发现在一个进程(Process)开始之前,外部可以随意通过这个Process的实例来更改它的属性,而一旦这个实例start以后,我就再也无法通过调用这个类的实例或者实例的方法来改变它的属性了。
下面是对照实验:

# -*- coding: utf8 -*-
import multiprocessing
from threading import Timer
import time

class Process(multiprocessing.Process):
    def __init__(self):
        super().__init__()
        self._active = True

    def run(self):
        # 将“暂停”的操作放在run()里面,可以成功改变p._active
        timer = Timer(2, p.pause)
        timer.start()
        self.action()

    def pause(self):
        print("paused")
        self._active = False

    def action(self):
        while self._active :
            print(self._active)
            time.sleep(0.5)
        print(self._active)

p = Process()
p.start()

运行结果:

True
True
True
True
paused
False

如果在p.start()之前直接执行p.pause(),其实也可以成功改变p._active的值。
所以我似乎发现一件事情,就是Process在start(变成一个进程)以后,它像是被整个打了个包丢进了另外一个“空间”(进程)里,我在外部操作Process的实例更改的它的属性和它正在运行的这个东西已经毫无关系了。
那么有没有什么办法可以在Process实例运行后在外部调用它的方法以更改它的属性呢?

阅读 4.3k
1 个回答

可以实现,使用multiprocessing.Value

multiprocessing.Value支持跨进程传递信息。
下面的代码通过Value('b', True/False)来传递布尔变量。

import multiprocessing
from multiprocessing import Value
from threading import Timer
import time

class Process(multiprocessing.Process):
    def __init__(self):
        super().__init__()
        self._active = Value('b', True)

    def run(self):
        self.action()

    def pause(self):
        print("paused")
        self._active.value = False

    def action(self):
        while self._active.value:
            print(self._active.value)
            time.sleep(0.5)
        print(self._active.value)

if __name__ == '__main__':
    p = Process()
    timer = Timer(2, p.pause)
    timer.start()
    #p.pause()
    p.start()

运行结果:

1
1
1
1
paused
0
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题