1.线程
线程有如下2种调用方式:
1、直接调用:
import threading import time def sayhi(num): #定义每个线程要运行的函数 print("running on number:%s" %num) time.sleep(3) if __name__ == '__main__': t1 = threading.Thread(target=sayhi,args=(1,)) #生成一个线程实例 t2 = threading.Thread(target=sayhi,args=(2,)) #生成另一个线程实例 t1.start() #启动线程 t2.start() #启动另一个线程 print(t1.getName()) #获取线程名 print(t2.getName())
2、类继承式调用:
import threading import time class MyThread(threading.Thread): def __init__(self,num): threading.Thread.__init__(self) self.num = num def run(self):#定义每个线程要运行的函数 print("running on number:%s" %self.num) time.sleep(3) if __name__ == '__main__': t1 = MyThread(1) t2 = MyThread(2) t1.start() t2.start()
join
join:等待线程执行完毕
1.join方法的作用是阻塞主进程(就是无法执行join以后的语句),专注执行多线程。
2.多线程多join的情况下,依次执行各线程的join方法,前头一个结束了才能执行后面一个。
3.无参数,则等待到该线程结束,才开始执行下一个线程的join。
4.设置参数后,则等待每个线程这么长时间就不管它了(而该线程并没有结束)。不管的意思就是可以执行后面的主进程了
daemon
Without daemon threads, you'd have to keep track of them, and tell them to exit, before your program can completely quit. By setting them as daemon threads, you can let them run and forget about them, and when your program quits, any daemon threads are killed automatically.
import threading import time import logging logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-9s) %(message)s',) def n(): logging.debug('Starting') logging.debug('Exiting') def d(): logging.debug('Starting') time.sleep(5) logging.debug('Exiting') if __name__ == '__main__': t = threading.Thread(name='non-daemon', target=n) d = threading.Thread(name='daemon', target=d) d.setDaemon(True) d.start() t.start()
As we can see from the output, it does not have "Exiting" message from the daemon thread, since all of the non-daemon threads (including the main thread) exit before the daemon thread wakes up from its five second sleep.
互斥锁
import time import threading def addNum(): global num #在每个线程中都获取这个全局变量 print('--get num:',num ) time.sleep(1) lock.acquire() #修改数据前加锁 num -=1 #对此公共变量进行-1操作 lock.release() #修改后释放 num = 100 #设定一个共享变量 thread_list = [] lock = threading.Lock() #生成全局锁 for i in range(100): t = threading.Thread(target=addNum) t.start() thread_list.append(t) for t in thread_list: #等待所有线程执行完毕 t.join() print('final num:', num )
递归锁
主要用于递归调用场景,
它有2个特性:
1、只有获取它的线程才可以释放该lock
2、一个线程可以多次获得lock
信号量:
互斥锁 同时只允许一个线程更改数据,而Semaphore是定义同时只允许一定数量的线程更改数据
event
An event is a simple synchronization object
the event represents an internal flag,and threads can wait for the flag to set ,or set or clear flag themselves
event = threading.Event()
# an client thread can wait for the flag to be set
event.wait()
# a server thread can set or reset it
event.set()
event.clear()
if the flag is set, the wait method doesn't be blocked
if the flag is cleared ,wait method will be blocked until it becomes set again
任意数量的线程可以等待同一个event
下面是一个红绿灯的例子:
import threading,time import random def light(): if not event.isSet(): event.set() #wait就不阻塞 #绿灯状态 count = 0 while True: if count < 10: print('