Python 线程复习
修改全局变量,设立flag来避免线程间数据冲突,低效率版
from threading import Thread import time g_num=0 g_flag = 1 def test1(): global g_num global g_flag if g_flag ==1: for i in range(1000000): g_num += 1 g_flag = 0 print('----test1----g_num=%d'%g_num) def test2(): global g_num global g_flag while True: if g_flag != 1: for i in range(1000000): g_num += 1 break print('----test2----g_num=%d' % g_num) p1 = Thread(target=test1) p1.start() p2 = Thread(target=test2) p2.start()
修改全局变量,互斥锁(高效版),否则不用枷锁
from threading import Thread,Lock import time g_num=0 def test1(): global g_num for i in range(1000000): mutex.acquire() # 上锁 g_num += 1 mutex.release() #解锁 print('----test1----g_num=%d'%g_num) def test2(): global g_num for i in range(1000000): mutex.acquire() # 上锁 g_num += 1 mutex.release() # 解锁 print('----test2----g_num=%d' % g_num) mutex = Lock() p1 = Thread(target=test1) p1.start() p2 = Thread(target=test2) p2.start()
死锁
添加超时时间 mutex.acquire(timeout = 1)
银行家算法-先满足最小需求单位,等待
ThreadLocal
可以解决线程间全局变量,不会因为线程修改全局变量而修改,完成数据间传递,不会因为程序一样而导致数据错乱
代码如下:
import threading # 创建全局变量threadLocal loacl_school = threading.local() def process_student(): # 获取当前线程关联的student std = loacl_school.student print(std) def process_thrad(name): # 绑定threadlocal的student loacl_school.student = name process_student() t1 = threading.Thread(target=process_thrad,args=('laowang',),name='thread-a') t2 = threading.Thread(target=process_thrad,args=('xiaowang',),name='thread-b') t1.start() t2.start() t1.join() t2.join()
异步
callback=func,并把之前函数返回值复制到func
GIL 全局解释器锁
解决办法:1、用多进程2、用C语言写关键部分
python部分
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
C语言代码
{ while(1){ ; }
}
生成libdealloop.so库
线程同步
import threading mylock = threading.RLock() num = 0 class myThread(threading.Thread): def __init__(self,name): threading.Thread.__init__(self,name=name) def run(self): global num while True: mylock.acquire() print('%s locked,Number:%d'% (threading.current_thread().name,num)) if num>=4: mylock.release() print('%s locked,Number:%d'% (threading.current_thread().name,num)) break num+=1 print('%s locked,Number:%d'% (threading.current_thread().name,num)) mylock.release() if __name__ =='__main__': thread1 = myThread('Thread_1') thread2 = myThread('Thread_2') thread1.start() thread2.start()