根据 https://github.com/joblib/joblib/issues/180,有没有一种安全的方法从python中的线程创建子进程? Python多处理模块不允许在线程内使用.这是真的?
我的理解是,从线程中分叉是好的,只要你没有持有线程.当你这样做时(在当前线程中?在进程中的任何地方?).但是,Python的文档没有说明在fork之后是否安全地共享threading.Lock对象.
还有这个:从日志记录模块共享的锁导致fork问题.https://bugs.python.org/issue6721
我不确定这个问题是怎么产生的.听起来当进程中的任何锁的状态都被复制到当前线程分叉的子进程中(这看起来像设计错误并且肯定会死锁).如果是这样,那么使用多真正提供对这种任何保护(因为我可以自由地创建我multiprocessing.Pool被创建和被其它线程进入后threading.Lock,经过线程已经开始,使用不是叉安全日志模块) - 多处理模块docs也没有说明是否应该在Locks之前分配multiprocessing.Pools.
用多处理替换threading.Lock.Lock到处避免这个问题并允许我们安全地组合线程和分支?
我遇到了从以下脚本收集日志的问题.一旦我设置SLEEP_TIME
为太"小"的值,LoggingThread线程就会以某种方式阻止日志记录模块.该脚本冻结了action
函数中的日志记录请求.如果SLEEP_TIME
大约为0.1,则脚本会按预期收集所有日志消息.
我试着按照这个答案,但它没有解决我的问题.
import multiprocessing
import threading
import logging
import time
SLEEP_TIME = 0.000001
logger = logging.getLogger()
ch = logging.StreamHandler()
ch.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(funcName)s(): %(message)s'))
ch.setLevel(logging.DEBUG)
logger.setLevel(logging.DEBUG)
logger.addHandler(ch)
class LoggingThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
while True:
logger.debug('LoggingThread: {}'.format(self))
time.sleep(SLEEP_TIME)
def action(i):
logger.debug('action: {}'.format(i))
def do_parallel_job():
processes = multiprocessing.cpu_count()
pool = multiprocessing.Pool(processes=processes)
for i in range(20):
pool.apply_async(action, args=(i,))
pool.close()
pool.join()
if __name__ == '__main__':
logger.debug('START')
#
# multithread part
#
for _ in range(10): …
Run Code Online (Sandbox Code Playgroud)