Python学习之线程
#线程锁 又叫 互斥锁(Mutex) import threading,time def run(n): lock.acquire() #申请锁 global num num+=1 time.sleep(1) lock.release() #释放锁 lock = threading.Lock() #生成实例 num = 0 t_obj = [] #存放线程实例 for i in range(1000): t = threading.Thread(target=run,args=("t-%s"%i,)) t.start() t_obj.append(t) #为了不阻塞后面线程的启动,不在这里join(),先放到列表里 for r in t_obj: #遍历线程实例列表,等待所有线程执行完毕 t.join() #join()的作用是为了防止子线程没结束主线程就先结束 # 表明主线程会等待子线程执行完毕再结束。 print("finished..",threading.current_thread(),threading.active_count()) print("num:",num) #ubuntu python2.6 可以看到num小于1000,原因如下 #python2.6每100条指令换一次gil锁,换线程执行 #thread线程执行,100条指令到了还没执行完,释放锁,不执行了,换thread2线程执行 #thread2申请锁,假设thread2执行完了,赋值count=1并释放锁 #这时thread1又可以(再次)执行了,申请gil锁,重复之前第一次执行的所有过程 #执行完count++,count=1,因为线程1执行了一半,记住了上下文放在寄存器里 #再次执行的时候从寄存器里拿数据,运算完还是1,把线程2的给覆盖了,结果还是1
每个线程都有他自己的一组CPU寄存器,称为线程的上下文,该上下文反映了线程上次运行该线程的CPU寄存器的状态。
# Python在同一时刻只允许一个线程修改数据,线程锁,解决上面问题
# 加了锁程序就变串行了,所以使用时数据量不要特别大,获取锁立刻释放
守护线程 import threading,time def run(n): print("task",n) time.sleep(2) print("done") start_time= time.time() for i in range(50): t = threading.Thread(target=run,args=("t-%s"%i,)) t.setDaemon(True) #把当前线程设置为守护线程,主线程结束整个程序结束 #socket一个连接启动一个线程,设置为守护线程,当socketserver停掉整个 #程序结束,不用等线程结束 t.start() #查看主线程和当前线程数 print("finished..",threading.current_thread(),threading.active_count()) print("cost:",time.time()-start_time)
简单线程 普通方法 import threading,time def run(n): print("task",n) time.sleep(2) t1=threading.Thread(target=run,args=("t1",)) t2=threading.Thread(target=run,args=("t2",)) t1.start() t2.start() 类方法 class MyThread(threading.Thread): def __init__(self,n): super(MyThread,self).__init__() self.n=n def run(self): #必须是run print("running task",self.n) t1=MyThread("t1") t2=MyThread("t2") t1.start() t2.start()
线程间通信,使用event # 通过Event来实现两个或多个线程间的交互,下面是一个红绿灯的例子, # 即起动一个线程做交通指挥灯,生成几个线程做车辆,车辆行驶按红灯# # 停,绿灯行的规则。 # event.setO # event.clear() # If the flag is set,the wait method doesn't do anything. # 标志位设定了,代表绿灯,直接通行 # If the flag is cleared,wait will block until it becomes set again. # 标志位被清空,代表红灯,wait等待变绿灯 # Any number of threads may wait for the same event. import time,threading event=threading.Event() def lighter(): count = 0 event.set() #先设置绿灯 while True: if count >5 and count <10: #改成红灯 event.clear() #把标志位清了 print("\033[41;1mred light is on...\033[0m") elif count>10: event.set() #变绿灯 print("\033[42;1mgreen light is on...\033[0m") count=0 else: print("\033[42;1mgreen light is on...\033[0m") time.sleep(1) count+=1 def car(name): while True: if event.is_set(): #代表绿灯 print("[%s] running..."%name) time.sleep(1) else: print("[%s] sees red light,waiting..." % name) event.wait() print("\033[34;1m[%s] green light is on, start going..." % name) light=threading.Thread(target=lighter,) light.start() car1 = threading.Thread(target=car,args=("tesila",)) car1.start()
线程间通信,使用event # 通过Event来实现两个或多个线程间的交互,下面是一个红绿灯的例子, # 即起动一个线程做交通指挥灯,生成几个线程做车辆,车辆行驶按红灯# # 停,绿灯行的规则。 # event.setO # event.clear() # If the flag is set,the wait method doesn't do anything. # 标志位设定了,代表绿灯,直接通行 # If the flag is cleared,wait will block until it becomes set again. # 标志位被清空,代表红灯,wait等待变绿灯 # Any number of threads may wait for the same event. import time,threading event=threading.Event() def lighter(): count = 0 event.set() #先设置绿灯 while True: if count >5 and count <10: #改成红灯 event.clear() #把标志位清了 print("\033[41;1mred light is on...\033[0m") elif count>10: event.set() #变绿灯 print("\033[42;1mgreen light is on...\033[0m") count=0 else: print("\033[42;1mgreen light is on...\033[0m") time.sleep(1) count+=1 def car(name): while True: if event.is_set(): #代表绿灯 print("[%s] running..."%name) time.sleep(1) else: print("[%s] sees red light,waiting..." % name) event.wait() print("\033[34;1m[%s] green light is on, start going..." % name) light=threading.Thread(target=lighter,) light.start() car1 = threading.Thread(target=car,args=("tesila",)) car1.start()