最新消息:XAMPP默认安装之后是很不安全的,我们只需要点击左方菜单的 "安全"选项,按照向导操作即可完成安全设置。

Python基础学习之多线程常用方法

XAMPP案例 admin 337浏览 0评论

0Python

目录

1、基于threading创建多线程

2、基于concurrent.futures创建线程池常用方法介绍示例3、基于multiprocessing.dummy创建线程池

线程基于进程创建,开销小,共享进程的资源,可自由通信,无法利用多核,不加锁修改进程资源也是不安全的【其他进程也可同时修改,除非该资源仅仅属于本进程,因GIL锁的存在,那么修改资源就是安全的】

1、基于threading创建多线程

import os
import time
from threading import Thread, get_ident


def task(i):
   print(f"进程{os.getpid()},创建线程:{get_ident()},执行任务:{i}")
   time.sleep(0.5)


if __name__ == '__main__':
   start = time.time()
   ts = []
   print(f"当前进程为:{os.getpid()},父进程为:{os.getppid()}")
   for j in range(5):
       t = Thread(target=task, args=(j,))
       t.start()
       ts.append(t)
   for j in ts:
       j.join()
   print(f"执行任务总耗时:{time.time() - start}")

2、基于concurrent.futures创建线程池

常用方法介绍
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor

# 通过其创建进程池和线程池,两者使用方法一致

1. 创建池子
pool = ProcessPoolExecutor(max_workers=线程数量,默认cpu个数的5倍)

2. 异步提交
pool.submit(func,*args,**kwargs) 返回任务结果预存的内存空间

3. map方式异步提交【等同于for+submit】
pool.map(func,*iterables,timeout=None,chunksize=1)

4. 回收池子资源及等待所有任务结束【类型进程池的close,join】
True 默认值,等待池中所有线程执行完所有的任务,才回收资源
False 立即返回,不等待池中线程是否执行完毕,可以执行主进程之后的代码,但同样会等所有的任务执行完毕
pool.shutdown(wait=True)  

5. 回调函数,池中某一线程一执行完就将结果传给指定的回调函数处理,map方式无法使用
pool.submit().add_done_callback(back_name)

6. 判断某一线程是否执行完毕
ret = pool.submit()
ret.done()

7. 取消某一个任务
ret = pool.submit()
ret.cancle()
示例
# 注意通过本模块创建进程池,使用方法完全一样,仅仅导入的类不同而已ProcessPoolExecutor
import os
import time
from concurrent.futures import ThreadPoolExecutor


def task(n):
   print(f"父进程{os.getpid()},用户{n}调用子线程执行任务")
   time.sleep(2)
   return n ** 2


if __name__ == '__main__':
   t_pool = ThreadPoolExecutor(max_workers=os.cpu_count() * 2)   # 创建线程池
   users = range(20)
   results = []
   for i in users:
       ret = t_pool.submit(task, i)   # 异步提交
       results.append(ret)    # 将线程结果对象收集
   t_pool.shutdown(wait=True)  # 等线程池中所有任务执行完毕后回收资源,否则立即回收,但都会等所有任务执行完才行
   for j in results:
       print(j.result())   # 获取子线程执行的结果
       
# map用法
if __name__ == '__main__':
   t_pool = ThreadPoolExecutor(max_workers=os.cpu_count() * 2)  # 创建线程池
   users = range(20)

   results = t_pool.map(task, users)
   t_pool.shutdown(wait=False)
   print("当wait为False时,上行代码执行完毕,不阻塞,直接执行本行代码")
   print(f"如果获取结果就会阻塞,结果为:{[i for i in results]}")
3、基于multiprocessing.dummy创建线程池
import os
from multiprocessing.dummy import Pool


def task(i):
   print(i)
   return i ** 2


if __name__ == '__main__':
   pool = Pool((os.cpu_count()) * 5)
   jobs = range(100)
   # 异步执行
   results = pool.map(task, jobs)
   pool.close()
   pool.join()
   print(results)

转载请注明:XAMPP中文组官网 » Python基础学习之多线程常用方法

您必须 登录 才能发表评论!