【问题标题】:Python: can't set Process variable from outside ProcessPython:无法从流程外部设置流程变量
【发布时间】:2014-05-09 13:11:16
【问题描述】:

我正在尝试从外部设置 Process 类的类变量,以指示进程内的 while 循环应该完成。

然而,虽然变量似乎设置得很好,但旧值是从run(self) 检索到的。我尝试过在此工作的地方使用 threading.Thread。但是,Thread 的问题在于它并不总是在调用 start() 时启动。有时它会等待scp 进程完成,这会扼杀在这种情况下使用线程的意义。

from multiprocessing import Process
        class LogParserThread(Process):
            def __init__(self):
                super(LogParserThread, self).__init__()
                self.scp_done = False
                self.flights_to_add = ()

            def stop(self):
                self.scp_done = True
                print 'Stopping: ' + str(self.scp_done)


            def run(self):
                file_list = ()
                while self.scp_done is False or len(file_list) > 0:
                    print 'Status ' + str(self.scp_done) + ' ' + str(len(file_list))
                    if (len(file_list) > 1):
                        print ' Case 1 '
                        f = file_list[0]
                        os.system('rm -rf ' + f + '*')
                    if (len(file_list) is 1 and self.scp_done is True):
                        print ' Case 2 '
                        f = file_list[0]
                        os.system('rm -rf ' + f + '*')
                    update file_list

        files_to_copy = "file1 file2 file3"
        parser_thread = LogParserThread()
        parser_thread.start()
        print 'BEFORE COPY ' + str(parser_thread.scp_done)
        os.system('scp -C remote:' + files_to_copy + ' ' + '/destination/')
        print 'AFTER COPY ' + str(parser_thread.scp_done)
        parser_thread.stop()
        print 'AFTER STOP ' + str(parser_thread.scp_done)
        parser_thread.join()
        print 'AFTER JOIN ' + str(parser_thread.scp_done)

这些是测试运行的打印结果:

BEFORE COPY: False
AFTER COPY False
Stopping: True
AFTER STOP True
Status False 1
Status False 1
Status False 1
Status False 1
Status False 1
Status False 1

【问题讨论】:

  • 进程默认不共享内存——每个进程都有自己的内存“片”。您可能想阅读the multiprocessing documentation on sharing state
  • os.system('rm -rf ' + f + '*'): rm -rf* 在同一个声明中吓坏了我。 :)
  • @unutbu :) 谢谢,文件不是很重要,但 * 并不是真正需要的
  • @goncalopp 但在这种情况下,如何更新我最初发送到进程的变量?

标签: python multithreading process python-multithreading


【解决方案1】:

在 Unix 上,子进程使用 os.fork 生成。 fork 复制全局变量(或使用copy-on-write),因此每个进程(父进程和子进程)都有自己的全局变量副本。在 Windows 上,会生成第二个 Python 进程并导入调用模块。 在任何一种情况下(在 Unix 或 Windows 上),当父级修改全局变量时,子级的同名全局变量都不会更改。因此在主进程中调用parser_thread.stop()不会影响子进程self.scp_done的值。

multiprocessing 确实提供了一些可以促进sharing state between processes 的对象,例如mp.Value。对于简单的布尔值,您还可以使用mp.Event

import multiprocessing as mp
import time

class LogParserProcess(mp.Process):
    def __init__(self):
        super(LogParserProcess, self).__init__()
        self.done = mp.Event()
        self.flights_to_add = ()

    def stop(self):
        self.done.set()
        print 'Stopping: ' + str(self.done.is_set())

    def run(self):
        file_list = ()
        while not self.done.is_set() or len(file_list) > 0:
            print 'Status ' + str(self.done.is_set()) + ' ' + str(len(file_list))

files_to_copy = "file1 file2 file3"
proc = LogParserProcess()
proc.start()
print 'BEFORE COPY ' + str(proc.done.is_set())
time.sleep(1)
print 'AFTER COPY ' + str(proc.done.is_set())
proc.stop()
print 'AFTER STOP ' + str(proc.done.is_set())
proc.join()
print 'AFTER JOIN ' + str(proc.done.is_set())

打印

BEFORE COPY False
Status False 0
...
Status False 0
AFTER COPY False
Status False 0
Status False 0
Status False 0
Stopping: True
AFTER STOP True
AFTER JOIN True

【讨论】:

    猜你喜欢
    • 2014-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2015-01-02
    • 2016-11-21
    相关资源
    最近更新 更多