线程
线程是计算机中被CPU调度的最小单位
线程:轻量级的进程/轻型进程,线程本身创建出来就是为了解决并发问题的,并且他的整体效率比进程要高,但是线程实际上也有一些性能上的限制,管理调度开销
如果你的程序需要数据隔离:多进程,如果你的程序对并发的要求非常高:多线程
python线程模块的选择
Python提供了几个用于多线程编程的模块,包括thread、threading和Queue等。thread和threading模块允许程序员创建和管理线程。thread模块提供了基本的线程和锁的支持,threading提供了更高级别、功能更强的线程管理的功能。Queue模块允许用户创建一个可以用于多个线程之间共享数据的队列数据结构。
避免使用thread模块,因为更高级别的threading模块更为先进,对线程的支持更为完善,而且使用thread模块里的属性有可能会与threading出现冲突;其次低级别的thread模块的同步原语很少(实际上只有一个),而threading模块则有很多;再者,thread模块中当主线程结束时,所有的线程都会被强制结束掉,没有警告也不会有正常的清除工作,至少threading模块能确保重要的子线程退出后进程才退出。
thread模块不支持守护线程,当主线程退出时,所有的子线程不论它们是否还在工作,都会被强行退出。而threading模块支持守护线程,守护线程一般是一个等待客户请求的服务器,如果没有客户提出请求它就在那等着,如果设定一个线程为守护线程,就表示这个线程是不重要的,在进程退出的时候,不用等待这个线程退出。
threading模块
线程的创建Threading.Thread类
import os,time from threading import Thread def func(): print('start',os.getpid()) time.sleep(0.1) print('end') t = Thread(target=func) t.start() for i in range(5): print('主进程/主线程',os.getpid()) 或 from threading import Thread import time class Sayhi(Thread): def __init__(self,name): super().__init__() self.name=name def run(self): time.sleep(2) print('%s say hello' % self.name) if __name__ == '__main__': t = Sayhi('egon') t.start() print('主线程')
进程与线程的效率对比
import time from threading import Thread def func(): n = 100 n ** 2 start = time.time() lst = [] for i in range(100): t = Thread(target=func) t.start() lst.append(t) for n in lst: n.join() print('线程:',time.time() -start) 结果: 线程: 0.017000913619995117 #线程的用时 import time from multiprocessing import Process def func(): t = 100 t ** 2 if __name__ == '__main__': start = time.time() lst = [] for i in range(100): p = Process(target=func) p.start() lst.append(p) for n in lst: n.join() print('进程:',time.time()-start) 结果: 进程: 5.655323505401611 #进程用时
线程的数据共享
from threading import Thread n = 100 def func(): global n n-=10 t = Thread(target=func) t.start() t.join() print(n) 结果: 90
Thread类的其他方法
Thread实例对象的方法 # isAlive(): 返回线程是否活动的。 # getName(): 返回线程名。 # setName(): 设置线程名。 threading模块提供的一些方法: # threading.currentThread(): 返回当前的线程变量。 # threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。 # threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
from threading import Thread import threading from multiprocessing import Process import os def work(): import time time.sleep(3) print(threading.current_thread().getName()) if __name__ == '__main__': #在主进程下开启线程 t=Thread(target=work) t.start() print(threading.current_thread().getName()) print(threading.current_thread()) #主线程 print(threading.enumerate()) #连同主线程在内有两个运行的线程 print(threading.active_count()) print('主线程/主进程') ''' 打印结果: MainThread <_MainThread(MainThread, started 140735268892672)> [<_MainThread(MainThread, started 140735268892672)>, <Thread(Thread-1, started 123145307557888)>] 主线程/主进程 Thread-1 ''' 代码示例
守护线程
import time from threading import Thread def func(): while True: print('in func') time.sleep(0.5) def func2(): print('start func2') time.sleep(10) print('end func2') Thread(target=func2).start() t = Thread(target=func) t.setDaemon(True) t.start() print('主线程') time.sleep(2) print('主线程结束')