python中线程的多处理并不能使每个子进程正常工作

时间:2019-08-22 00:29:37

标签: python multithreading multiprocessing

使用python中的threading模块在​​每个线程中执行子进程时,某些进程无法正常启动和挂起,如示例代码的输出。

由于python中的IPC,启动进程似乎需要排他控制。是吗?

具有线程锁定功能,它可以完美工作。我只想创建一个线程来控制子进程的生死管理。

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

import multiprocessing
import threading

import fire
from logzero import logger


def process_method():
    logger.info("process log")


def start_process():
    logger.info("starting thread")
    process = multiprocessing.Process(target=process_method)
    process.daemon = True
    process.start()
    process.join()


def main(num_of_threads=3):
    threads = []
    for _ in range(num_of_threads):
        t = threading.Thread(target=start_process)
        t.daemon = True
        t.start()
        threads.append(t)
    for t in threads:
        t.join()
    logger.info("program done")


if __name__ == "__main__":
    fire.Fire(main)

输出

$ python '/tmp/tmp.lY3YDIltYg/test.py' 30
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:16] process log
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:20] starting thread
[I 190822 09:10:38 test:16] process log
[I 190822 09:10:38 test:16] process log
[I 190822 09:10:38 test:16] process log
[I 190822 09:10:38 test:16] process log
[I 190822 09:10:38 test:16] process log

环境

  • python 3.6
  • ubutu 64位

1 个答案:

答案 0 :(得分:2)

我假设您使用的是类似UNIX的系统?因为如果是这样,那么您在这里做的不好。 mixing fork with threads is a bad idea,在类似UNIX的系统上Python的class SimpleMap extends Component { constructor(props) { super(props); // Filling our parent container this.state = { mapStyles: { width: "100%", height: "100%" } }; } render() { return ( // Wrapping your component on a relative div container with the desired size <div style={{ position: 'relative', width: '100vw', height: '40vh' }}> <Map google={this.props.google} zoom={15} style={this.state.mapStyles} initialCenter={{ lat: 40, lng: -80 }} > <Marker position={{ lat: 40, lng: -80 }} /> </Map> </div> ); } } 的默认实现使用Process,因此,通过在线程中启动fork es,您可以Process来自多线程进程。

这里有两种解决方案:

  1. 停止使用线程。您的线程在这里不是必需的,因为它们实际上并不管理生命周期(线程和进程都是fork s,因此当主进程的主线程完成时,它们将被毫不客气地杀死)。
  2. 如果必须使用线程,并且使用的是Python 3.4+,则可以切换to the fork-server start method(或daemon方法以使代码可移植到Windows,但要花费{{ 1}}在类似UNIX的系统上创建会稍微慢一些,因此,从主进程执行的唯一'spawn'是在启动任何线程之前完成的,而以后所有的Process都是从(无线程的)完成的分支服务器。您要做的就是将fork作为fork防护之后的第一行。