【问题标题】:Python, using threading with multiprocessingPython,使用多处理线程
【发布时间】:2017-01-27 03:06:47
【问题描述】:

有人可以解释为什么线程在 multiprocessing.Process 中不起作用。

我附上了一些例子来解释我的问题。

我有一个每秒执行一次并写入文件的进程。当我从 shell 运行它时,它按预期工作。

stat_collect.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from threading import Timer
from os import path
from datetime import datetime

STAT_DATETIME_FMT = '%Y-%m-%d %H:%M:%S'


def collect_statistics():
    my_file = 'test.file'
    if not path.exists(my_file):
        with open(my_file, 'w') as fp:
            fp.write(datetime.now().strftime(STAT_DATETIME_FMT) + '\n')
    else:
        with open(my_file, 'a') as fp:
            fp.write(datetime.now().strftime(STAT_DATETIME_FMT) + '\n')

    Timer(1, collect_statistics).start()


if __name__ == '__main__':
    collect_statistics()

当我尝试从其他脚本运行它时(在后台工作):

#!/usr/bin/env python

from multiprocessing import Process
from stat_collect import collect_statistics  # logger sc

if __name__ == '__main__':
    # This don't work
    p = Process(target=collect_statistics)
    p.start()

    while True:
        pass

方法 collect_statistics 只执行一次,但如果我使用 Thread(target=collect_statistics).start() 它就像我从 shell 运行它一样工作。为什么会这样?

【问题讨论】:

    标签: python multithreading python-multiprocessing


    【解决方案1】:

    这是怎么回事:

    1. 你开始你的过程
    2. collect_statistics 运行
    3. 定时器已启动
    4. 现在进程中调用的函数(collect_statistics)已经完成,所以进程 退出,同时终止计时器。

    以下是解决方法:

    stat_collect.py

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    from threading import Timer
    from os import path
    from datetime import datetime
    import time
    
    STAT_DATETIME_FMT = '%Y-%m-%d %H:%M:%S'
    
    
    def collect_statistics():
        while True:
            my_file = 'test.file'
            if not path.exists(my_file):
                with open(my_file, 'w') as fp:
                    fp.write(datetime.now().strftime(STAT_DATETIME_FMT) + '\n')
            else:
                with open(my_file, 'a') as fp:
                    fp.write(datetime.now().strftime(STAT_DATETIME_FMT) + '\n')
    
            time.sleep(1)
    
    
    if __name__ == '__main__':
        collect_statistics()
    

    对于调用脚本:

    #!/usr/bin/env python
    
    from multiprocessing import Process
    from stat_collect import collect_statistics  # logger sc
    
    if __name__ == '__main__':
        # This don't work
        p = Process(target=collect_statistics)
        p.start()
        p.join() # wait until process is over, e.g forever
    

    p.join() 只是在这里替换你的无限 while 循环,这会占用大量资源。

    【讨论】:

    • 那么,调用 Process 和从命令行运行 stat_collect.py 不一样?为什么 Timer 在从 Process 运行时会被杀死,而在从命令行运行脚本时不会被杀死?
    • 你应该看看python的GIL。基本上在 Python 中,2 个进程根本不相互通信。从命令行运行在单个进程中运行您的代码,并且所有变量(Timer)都是“共享的”。在另一个进程中运行会创建一个父进程(调用脚本)和一个子进程(使用p=Process(...) 创建)。父进程不与子进程通信,也不知道另一个线程已经启动。
    猜你喜欢
    • 2013-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-30
    • 1970-01-01
    • 1970-01-01
    • 2014-05-25
    • 2013-03-11
    相关资源
    最近更新 更多