进程:全局变量、函数里变量每个进程都是独立的
线程:全局变量是共享的,函数里的变量每个线程都是独立的
生产者消费者问题,为了解决解耦问题。
一、使用Thread创建多线程
from threading import Thread import time def test(): print("---昨天晚上喝多了,下次少喝点---") time.sleep(1) for i in range(5): t=Thread(target=test) t.start()
二、使用threading.Thread子类创建多线程
import threading import time class MyThread(threading.Thread): def run(self): for i in range(3): time.sleep(1) msg="I'm "+self.name+' @ '+str(i) #name属性中保存的是当前线程的名字 print(msg) if __name__=='__main__': t=MyThread() t.start() t2=MyThread() t2.start()
import threading import time class MyThread(threading.Thread): def run(self): for i in range(3): time.sleep(1) msg="I'm "+self.name+' @ '+str(i) #name属性中保存的是当前线程的名字 print(msg) def test(): for i in range(5): t = MyThread() t.start() if __name__=='__main__': test()
三、线程共享全局变量
from threading import Thread import time g_num=100 def work1(): global g_num for i in range(3): g_num+=1 print("----in work1,g_num is %d----"%g_num) def work2(): global g_num print("----in work2,g_num is %d----"%g_num) print("---创建线程之前g_num is %d---"%g_num) t1=Thread(target=work1) t1.start() time.sleep(1) t2=Thread(target=work2) t2.start()
四、避免全局变量被修改,互斥锁
from threading import Thread,Lock import time g_num=0 def work1(): global g_num for i in range(100000): mutex.acquire() g_num+=1 mutex.release() print("----in work1,g_num is %d----"%g_num) def work2(): global g_num for i in range(100000): mutex.acquire() g_num+=1 mutex.release() print("----in work2,g_num is %d----"%g_num) def work3(): global g_num for i in range(100000): mutex.acquire() g_num+=1 mutex.release() print("----in work3,g_num is %d----"%g_num) print("---创建线程之前g_num is %d---"%g_num) mutex = Lock() #创建一把互斥锁 t1=Thread(target=work1) t1.start() #time.sleep(1) t2=Thread(target=work2) t2.start() t3=Thread(target=work3) t3.start()
五、死锁的解决
import threading import time class MyThread1(threading.Thread): def run(self): if mutexA.acquire(timeout=2): #mutexA.acquire(blocking=True,timeout=-1) 表示阻塞方式,超时时间 print(self.name+"t1-----------up") time.sleep(1) if mutexB.acquire(timeout=2): print(self.name+"t1-----------down") mutexB.release() mutexA.release() class MyThread2(threading.Thread): def run(self): if mutexB.acquire(timeout=2): print(self.name+"t2-----------up") time.sleep(1) if mutexA.acquire(timeout=2): print(self.name+"t2-----------down") mutexA.release() mutexB.release() mutexA=threading.Lock() mutexB=threading.Lock() if __name__=="__main__": t1 = MyThread1() t2 = MyThread2() t1.start() t2.start()
六、同步
import threading import time class MyThread1(threading.Thread): def run(self): while True: if mutexA.acquire(): #mutexA.acquire(blocking=True,timeout=-1) 表示阻塞方式,超时时间 print("aaaaaaaaaaaaaaaaa") mutexB.release() class MyThread2(threading.Thread): def run(self): while True: if mutexB.acquire(): #mutexA.acquire(blocking=True,timeout=-1) 表示阻塞方式,超时时间 print("bbbbbbbbbbbbbbbbb") mutexC.release() class MyThread3(threading.Thread): def run(self): while True: if mutexC.acquire(): #mutexA.acquire(blocking=True,timeout=-1) 表示阻塞方式,超时时间 print("ccccccccccccccccc") mutexA.release() mutexA=threading.Lock() mutexB=threading.Lock() mutexC=threading.Lock() mutexA.acquire() mutexB.acquire() if __name__=="__main__": t1 = MyThread1() t2 = MyThread2() t3 = MyThread3() t1.start() t2.start() t3.start()
七、生产者-消费者问题
import threading import time from queue import Queue class Producer(threading.Thread): def run(self): global queue count=0 while(True): if queue.qsize()<1000: for i in range(100): count+=1 msg="生产产品"+str(count) queue.put(msg) print(msg) time.sleep(0.5) class Consumer(threading.Thread): def run(self): global queue while(True): if queue.qsize()>100: for i in range(3): msg=self.name+"消费了"+queue.get() print(msg) time.sleep(1) if __name__ == "__main__": queue=Queue() for i in range(500): queue.put("初始产品"+str(i)) for i in range(2): pro=Producer() pro.start() for i in range(5): con=Consumer() con.start()
八、使用全局字典和threading.local 全局变量存储线程信息
import threading import time global_dict={} def std_thread(name,score): global_dict[threading.current_thread()]=name t2(score) t1() def t1(): time.sleep(1) print(global_dict[threading.current_thread()]) def t2(num): global_dict[threading.current_thread()] = num if __name__ == "__main__": th1=threading.Thread(target=std_thread,args=("历史",98)) th2=threading.Thread(target=std_thread,args=("化学",73)) th1.start() th2.start() th1.join() th2.join()
import threading import time global_local=threading.local() def std_thread(name,score): global_local.stu=name t2(score) t1() def t1(): time.sleep(1) print(global_local.stu) def t2(num): global_local.stu = num if __name__ == "__main__": th1=threading.Thread(target=std_thread,args=("历史",98)) th2=threading.Thread(target=std_thread,args=("化学",73)) th1.start() th2.start() th1.join() th2.join()
九、异步
from multiprocessing import Pool import time import os def test(): print("进程池中的进程pid=%d,ppid=%d"%(os.getpid(),os.getppid())) for i in range(3): print("----%d----"%i) time.sleep(1) return "hahah" def test2(args): print("---callback func---pid=%d,ppid=%d"%(os.getpid(),os.getppid())) print("---callback func--args=%s"%args) pool=Pool(3) pool.apply_async(func=test,callback=test2) time.sleep(5) print("主进程pid是:%d"%os.getpid())
十、GIL问题(嵌套c语言代码)
from ctypes import * from threading import Thread #加载动态库 lib=cdll.LoadLibrary("./libdeadloop.so") #创建一个子线程,让其执行c语言编写的函数,此函数是一个死循环 t=Thread(target=lib.DeadLoop) t.start() #主线程,也调用c语言编写的那个死循环函数 lib.DeadLoop() while True: pass void DeadLoop() { while(1) { ; } }