线程同步的问题主要是出现在多个线程对同一个共享资源进行访问时,可能会出现一些问题,为了保证数据的安全性和准确性,需要对多线程进行同步,保证一个时刻,只有一个线程在对共享资源进行访问。
先看例子,
import threading,time testList = [0] * 10 #生成一个有10个0的List
def task1(): for i in range(len(testList)): testList[i]=1 time.sleep(1) #task1将所有0改为1 def task2(): for i in range(len(testList)): print("-------------->" + str(testList[i])) time.sleep(1) #task2打印
if __name__ == '__main__': t1=threading.Thread(target=task1) t2=threading.Thread(target=task2) t1.start() t2.start() t1.join() t2.join() print(testList)
执行结果如下:
-------------->1 -------------->0 -------------->1 -------------->0 -------------->0 -------------->0 -------------->1 -------------->0 -------------->0 -------------->1 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] Process finished with exit code 0
这个例子中,有两个线程,一个线程负责将List里面的数字全部改成1,另一个线程负责打印。执行结果显示,0和1一直在交替出现,说明两个线程一直在同时处理testList这个列表
接下来看下一个例子:
import threading, time testList = [0] * 10 lock = threading.Lock() def task1(): lock.acquire() #获取线程锁,如果已经上锁,则等待锁释放 for i in range(len(testList)): testList[i] = 1 time.sleep(1) lock.release() #释放线程锁 def task2(): lock.acquire() #获取线程锁,如果已经上锁,则等待锁释放 for i in range(len(testList)): print("-------------->" + str(testList[i])) time.sleep(1) lock.release()#释放线程锁 if __name__ == '__main__': t1 = threading.Thread(target=task1) t2 = threading.Thread(target=task2) t1.start() t2.start() t1.join() t2.join() print(testList)
这次执行的结果如下:
-------------->1
-------------->1
-------------->1
-------------->1
-------------->1
-------------->1
-------------->1
-------------->1
-------------->1
-------------->1
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
总结:
使用 Thread 对象的 Lock 和 Rlock 可以实现简单的线程同步,这两个对象都有 acquire 方法和 release 方法,对于那些需要每次只允许一个线程操作的数据,可以将其操作放到 acquire 和 release 方法之间