主要内容:
线程的一些其他方法
线程事件
线程队列
线程池
GIL锁
协程
Greenlet
Gevent
一. 线程(threading)的一些其他方法
from threading import Thread import threading import time def work(): time.sleep(1) print("子线程对象>>>", threading.current_thread()) # 子线程对象 print("子线程名称>>>", threading.current_thread().getName()) # 子线程名称 print("子线程ID>>>", threading.get_ident()) # 子线程ID if __name__ == '__main__': t = Thread(target=work) # 创建子线程 t.start() # 开启子线程 print("主线程对象>>>", threading.current_thread()) # 主线程对象 print("主线程名称>>>", threading.current_thread().getName()) # 主线程名称 print("主线程ID>>>", threading.current_thread().ident) # 主线程ID print("主线程ID>>>", threading.get_ident()) # 主线程ID time.sleep(1) # 阻塞住,此时主线程代码运行的同时子线程代码也在运行 print(threading.enumerate()) # 拿到所有正在运行的线程对象(包括主线程) print(threading.active_count()) # 拿到所有正在运行的线程对象的数量 print("主线程/主进程执行完毕")
二. 线程事件
同进程的一样. 线程的一个关键特性是每个线程都是独立运行且状态不可预测。如果程序中的其他线程需要通过判断某个线程的状态来确定自己下一步的操作,这时线程同步问题就会变得非常棘手。为了解决这些问题,我们需要使用threading库中的Event对象。 对象包含一个可由线程设置的信号标志,它允许线程等待某些事件的发生。在初始情况下,Event对象中的信号标志被设置为假。如果有线程等待一个Event对象, 而这个Event对象的标志为假,那么这个线程将会被一直阻塞直至该标志为真。一个线程如果将一个Event对象的信号标志设置为真,它将唤醒所有等待这个Event对象的线程。如果一个线程等待一个已经被设置为真的Event对象,那么它将忽略这个事件, 继续执行.
事件的基本方法:
event.isSet():返回event的状态值; event.wait():如果 event.isSet()==False将阻塞线程; event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度; event.clear():恢复event的状态值为False。
举例说明:
有多个工作线程尝试链接MySQL,我们想要在链接前确保MySQL服务正常才让那些工作线程去连接MySQL服务器,如果连接不成功,都会去尝试重新连接。我们现在采用threading.Event机制来协调各个工作线程的连接操作.
MySQL简述:
mysql就是一个数据库,存数据用的东西,它就像一个文件夹,里面存着很多的excel表格,我们可以在表格里面写数据,存数据。但是如果我们要使用数据库,我们必须先要去连接它,你和他建立了连接关系,你才能操作它里面存放的数据。
模拟一个场景,开启两个线程:
线程一: 连接数据库,这个线程需要等待一个信号,告诉我们双方之间的网络是可以连通的.
线程二:检测与数据库之间的网络是否联通,并发送一个可联通或者不可联通的信号.
from threading import Thread,Event import threading import time,random def conn_mysql(): count=1 while not event.is_set(): if count > 3: raise TimeoutError('链接超时') #自己发起错误 print('<%s>第%s次尝试链接' % (threading.current_thread().getName(), count)) event.wait(0.5) # count+=1 print('<%s>链接成功' %threading.current_thread().getName()) def check_mysql(): print('