示例代码:https://github.com/lotapp/BaseCode/tree/master/python/5.concurrent/Thread
终于说道线程了,心酸啊,进程还有点东西下次接着聊,这周4天外出,所以注定发文少了 +_+
用过Java或者Net的重点都在线程这块,Python的重点其实在上篇,但线程自有其独到之处~比如资源共享(更轻量级)
这次采用循序渐进的方式讲解, 先使用,再深入,然后扩展,最后来个案例
,呃.呃.呃.先这样计划~欢迎纠正错误
官方文档:https://docs.python.org/3/library/threading.html
进程是由若干线程组成的(一个进程至少有一个线程)
用法和 Process
差不多,咱先看个案例: Thread(target=test,args=(i,))
import osfrom threading import Thread, current_thread def test(name): # current_thread()返回当前线程的实例 thread_name = current_thread().name # 获取线程名 print(f"[编号:{name}],ThreadName:{thread_name}\nPID:{os.getpid()},PPID:{os.getppid()}")def main(): t_list = [Thread(target=test, args=(i, )) for i in range(5)] for t in t_list: t.start() # 批量启动 for t in t_list: t.join() # 批量回收 # 主线程 print(f"[Main]ThreadName:{current_thread().name}\nPID:{os.getpid()},PPID:{os.getppid()}")if __name__ == '__main__': main()
输出:(同一个进程ID)
[编号:0],ThreadName:Thread-1PID:20533,PPID:19830[编号:1],ThreadName:Thread-2PID:20533,PPID:19830[编号:2],ThreadName:Thread-3PID:20533,PPID:19830[编号:3],ThreadName:Thread-4PID:20533,PPID:19830[编号:4],ThreadName:Thread-5PID:20533,PPID:19830[Main]ThreadName:MainThreadPID:22636,PPID:19830
注意一点:Python里面的线程是Posix Thread
如果想给线程设置一个Div的名字呢?:
from threading import Thread, current_threaddef test(): # current_thread()返回当前线程的实例 print(f"ThreadName:{current_thread().name}")def main(): t1 = Thread(target=test, name="小明") t2 = Thread(target=test) t1.start() t2.start() t1.join() t2.join() # 主线程 print(f"[Main],ThreadName:{current_thread().name}")if __name__ == '__main__': main()
输出:(你指定有特点的名字,没指定就使用默认命令【联想古时候奴隶名字都是编号,主人赐名就有名了】)
ThreadName:小明ThreadName:Thread-1[Main],ThreadName:MainThread
类的方式创建线程
from threading import Threadclass MyThread(Thread): def __init__(self, name): # 设个坑,你可以自行研究下 super().__init__() # 放在后面就报错了 self.name = name def run(self): print(self.name)def main(): t = MyThread(name="小明") t.start() t.join()if __name__ == '__main__': main()
输出:(和Thread初始化的name冲突了【变量名得注意哦】)
小明
from multiprocessing.dummy import Pool as ThreadPool, current_processdef test(i): # 本质调用了:threading.current_thread print(f"[编号{i}]{current_process().name}")def main(): p = ThreadPool() for i in range(5): p.apply_async(test, args=(i, )) p.close() p.join() print(f"{current_process().name}")if __name__ == '__main__': main()
输出:
[编号0]Thread-3[编号1]Thread-4[编号3]Thread-2[编号2]Thread-1[编号4]Thread-3MainThread
对上面代码,项目里面一般都会这么优化:(并行这块线程后面会讲,不急)
from multiprocessing.dummy import Pool as ThreadPool, current_processdef test(i): # 源码:current_process = threading.current_thread print(f"[编号{i}]{current_process().name}")def main(): p = ThreadPool() p.map_async(test, list(range(5))) p.close() p.join() print(f"{current_process().name}")if __name__ == '__main__': main()
输出:
[编号0]Thread-2[编号1]Thread-4[编号2]Thread-3[编号4]Thread-2[编号3]Thread-1MainThread
代码改动很小(循环换成了map)性能提升很明显(密集型操作)
Thread初始化参数:
Thread实例对象的方法:
threading模块提供的一些方法:
看一个小案例:
import timefrom threading import Thread, active_countdef test1(): print("test1") time.sleep(1) print("test1 ok")def test2(): print("test2") time.sleep(2) print("test2 ok")def main(): t1 = Thread(target=test1) t2 = Thread(target=test2, daemon=True) t1.start() t2.start() t1.join() print(active_count()) print(t1.is_alive) print(t2.is_alive) # t2.join() # 除非加这一句才等daemon线程,不然直接不管了if __name__ == '__main__': main()
下次就以 multiprocessing.dummy
模块为例了,API和 threading
几乎一样,进行了一些并发的封装,性价比更高
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。