多线程与多进程的一次使用记录@渊季
多线程
1、第一种方法
import threading
def run(name):
print(name)
ts = []
for i in range(10):
t = threading.Thread(target=run, args=(i,)) # 线程任务
ts.append(t)
for t in ts:
t.setDaemon(True) # 主进程 死亡线程随之消失
t.start()
for t in ts:
t.join()
2、第二种方法(线程池)
import time
from concurrent.futures import ThreadPoolExecutor
executor = ThreadPoolExecutor(20) # 线程池
def run(name):
print(name)
time.sleep(20)
print("Over", name)
for i in range(10):
executor.submit(run, i) # 添加 线程任务
executor.shutdown(wait=True) # 等待任务运行 完成
线程间的数据分配与 交互 可以使用
Queue
队列进行分配任务
补充
多线程 获取返回值的方式:
第一种可以通过 上面提到的队列的方式获取结果;
第二种可以通过 submit
的任务分配方式获取 结果 例子如下
from concurrent.futures import ThreadPoolExecutor, as_completed
def thread_function(age):
return age + 1
def run_thread_pool_sub(target, args, max_work_count=3):
executor = ThreadPoolExecutor(max_workers=max_work_count)
# with ThreadPoolExecutor(max_workers=max_work_count) as t:
res = [executor.submit(target, i) for i in args]
return res
if __name__ == '__main__':
ages = [1, 3, 4]
res = run_thread_pool_sub(thread_function, ages)
for future in as_completed(res):
data = future.result()
print(data)
多进程
1、第一种方式
import time
from multiprocessing import Process
def run(name):
print(name)
time.sleep(20)
print("Over", name)
if __name__ == '__main__': # 必须存在 用来 限制 进程
process_list = []
for i in range(5):
p = Process(target=run, args=(i,)) # 实例化进程对象
p.start()
process_list.append(p)
for p in process_list:
p.join()
print('结束测试')
2、第二种方式(进程池)
import time
from multiprocessing import Pool
def run(name):
print(name)
time.sleep(20)
print("Over", name)
def main():
pool = Pool(5) # 创建一个5个进程的进程池
for i in range(5):
pool.apply_async(func=run, args=(i,))
time.sleep(2)
pool.close()
pool.join()
print("抓价")
if __name__ == '__main__': # 必须存在 用来 限制 进程
main()
进程间的通信 可以使用
Pipe
管道 进行任务分配
注:如果 if name == ‘main’: 不存在就会报错如下:
RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.
This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:
if __name__ == '__main__':
freeze_support()
...
The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce an executable.
注意 python 的线程并非使用的越多越快,当达到一定极限速度还会降低,注意线程进程的合理分配,线程之间需要注意使用线程锁;
如果使用 多进程+多线程 的方式运行发现 程序线程没有正常启动直接消失结束,需要注意看是否线程有堵塞;