4 python multithreading threadpoolexecutor
作为对这个问题的跟进,我有一个简单的脚本,它开始threadpoolexecutor读取json文件。这样做时,我想使用for循环从 1 到 9 计数。出于某种原因,即使我使用executor.shutdown(wait=False)它仍然阻塞并等待read_employees方法执行。
根据文档:
如果 wait 为 False,则此方法将立即返回,并且当所有挂起的期货执行完毕后,将释放与执行程序关联的资源
import concurrent.futures
import json
import time
def read_employees(read_file):
with open(read_file) as f_obj:
employees = json.load(f_obj)
for emp in employees:
print(emp)
time.sleep(3)
def start_thread():
filename = 'employee.json'
with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
executor.submit(read_employees, filename)
executor.shutdown(wait=False)
def print_number():
for num in range(1,10):
time.sleep(2)
print(num)
start_thread()
print_number()
Run Code Online (Sandbox Code Playgroud)
如果我要这样做:
def read_employees(read_file):
with open(read_file) as f_obj:
employees = json.load(f_obj)
for emp in employees:
time.sleep(5)
print(emp)
def print_number():
for num in range(1,10):
print(num)
filename = 'employee.json'
empThread = threading.Thread(target=read_employees, args=(filename,))
empThread.start()
print_number()
Run Code Online (Sandbox Code Playgroud)
先从1数到9,然后打印出员工,延迟是因为在读取员工时睡觉。像这样:
1
2
3
4
5
6
7
8
9
ams@yourcompanyname.com
bcs@yourcompanyname.com
Run Code Online (Sandbox Code Playgroud)
如何使用threadpoolexecutor无阻塞实现相同的输出?
Mic*_*dam 10
我建议你不要使用with声明。一个with声明通过调用关闭__exit__一个方法上下文管理。上下文管理器是任何实现__enter__and__exit__方法的类。因此,在with语句中运行__exit__完所有内容后,它会调用传入的上下文管理器。
在这种情况下,ThreadPoolExecutor是上下文管理器。ThreadPoolExecutor是 的子类Executor。所以通过引用Executor的类定义,我们可以看到__exit__它调用的方法self.shutdown(wait=True)。
那个调用self.shutdown(wait=True)就是问题所在。如果您遵循上下文管理器的工作方式,因为self.shutdown(wait=False)是您with语句中的最后一件事,__exit__将在之后直接调用。这意味着self.shutdown(wait=True)将被调用。所以这就是阻碍你的原因。
您有两个选择来解决这个问题。第一个是子类化ThreadPoolExecutor并重写__exit__方法。
第二种选择是做这样的事情:
def start_thread():
filename = 'employee.json'
executor = concurrent.futures.ThreadPoolExecutor(max_workers=2)
executor.submit(read_employees, filename)
executor.shutdown(wait=False)
Run Code Online (Sandbox Code Playgroud)
可能是由于这个小片段:
“如果使用该语句,则可以避免必须显式调用此方法with,这将关闭Executor(等待就像Executor.shutdown()使用waitset to调用一样True)”
https://docs.python.org/3/library/concurrent.futures.html