Python类实例成员变量不在线程内更新

时间:2018-01-15 02:56:03

标签: python multithreading

当前创建我的类的单独实例Example,然后为每个实例创建一个线程,并使用Class的execute_thread函数作为线程函数目标。只要成员变量exit_signal未更新为True,线程函数就会继续运行。一旦在键盘上按下control,shift和2,就不会从线程实例中更新成员变量。

问题是线程函数不识别成员变量的任何变化,为什么它没有检测到变化,是否循环阻止它这样做?

import keyboard
import multiprocessing
import time


class Example:

    m_exit_signal = False

    def __init__(self):
        keyboard.add_hotkey('control, shift, 2', lambda: self.exit_signaled())

    def execute_example_thread(self):

        exit_status = self.m_exit_signal

        # THREAD continues till exit is called! -
        while exit_status == False:

            time.sleep(5)

            exit_status = self.m_exit_signal

            print(exit_status)

    def exit_signaled(self):
        self.m_exit_signal = True
        print("Status {0}".format(self.m_exit_signal))


example_objects = []
example_objects.append(Example())
example_objects.append(Example())
example_threads = []

for value in example_objects:
    example_threads.append(multiprocessing.Process(target=value.execute_example_thread, args=()))
    example_threads[-1].start()

1 个答案:

答案 0 :(得分:0)

多处理会分叉您的代码,使其在单独的进程中运行。在上面的代码中,键盘回调调用父进程中存在的实例中的方法。循环(以及类实例的副本)实际上是在子进程中的分叉版本中运行的。为了向孩子发出信号,你需要在他们之间共享一个变量并使用它来回传递数据。请尝试下面的代码。

import keyboard
import multiprocessing as mp
import time

class Example(object):
    def __init__(self, hot_key):
        self.run = mp.Value('I', 1)
        keyboard.add_hotkey('control, shift, %d' % hot_key, self.exit_signaled)
        print("Initialized {}".format(mp.current_process().name))

    def execute(self):
        while self.run.value:
            time.sleep(1)
            print("Running {}".format(mp.current_process().name))
        print("{} stopping".format(mp.current_process().name))

    def exit_signaled(self):
        print("exit signaled from {}".format(mp.current_process().name))
        self.run.value = 0

p1 = mp.Process(target=Example(1).execute)
p1.start()
time.sleep(0.1)
p2 = mp.Process(target=Example(2).execute)
p2.start()

这里每个实例的父节点和子节点共享self.run = mp.Value要共享数据,您需要使用其中一个,而不仅仅是任何python变量。