使用Thread对象的Lock和RLock可以实现简单的线程同步,这两个对象都有acquire方法和release方法。对于共享数据,可以将操作放到acquire和release方法之间。
考虑这样一种情况:一个列表里所有元素都是0,线程set从后向前把所有的元素改成1,而线程print负责从前往后读取列表并输出,
线程set开始改的时候,线程print可能就来输出列表了,输出结果就成了一半0一半1,这就是数据不同步的问题。为了避免这种问题,引入了锁的概念。
锁有两种状态——锁定和未锁定。当一个线程(set)要访问共享数据是,必须先获得锁定;如果已经有别的线程(print)获得锁定了,就让set暂停,也就是同步阻塞;等到线程print访问完毕,释放锁后,再让set线程继续。
经过这样的处理,输出列表要么全部是1,要么全部输出0,不会出现一半1一半0的尴尬场面。
#! /usr/bin/evn python
#-*- coding:utf-8 -*-
import threading
from time import sleep
from datetime import datetime
date_time_format="%y-%M-%d %H:%M:%S"
class MyThread(threading.Thread):
def __init__(self,threadID,name,counter):
threading.Thread.__init__(self)
self.threadID=threadID
self.name=name
self.counter=counter
def run(self):
print("开启线程:"+self.name)
#获取锁,用于线程同步
threadLock.acquire()
print_time(self.name,self.counter,3)
#释放锁
threadLock.release()
def date_time_str(date_time):
return datetime.strftime(date_time,date_time_format)
def print_time(threadNmae,delay,counter):
while counter:
sleep(delay)
print("%s:%s"%(threadNmae,date_time_str(datetime.now())))
counter-=1
def main():
#create new thread
thread1=MyThread(1,"Thread-1",1)
thread2=MyThread(2,"Thread-2",2)
#start new thread
thread1.start()
thread2.start()
#添加线程到线程列表
threads.append(thread1)
threads.append(thread2)
#等待所用线程完成
for t in threads:
t.join()
print('退出主线程')
if __name__=='__main__':
threadLock=threading.Lock()
threads=[]
main()
执行结果:
开启线程:Thread-1
开启线程:Thread-2
Thread-1:17-02-04 21:02:07
Thread-1:17-02-04 21:02:08
Thread-1:17-02-04 21:02:09
Thread-2:17-02-04 21:02:11
Thread-2:17-02-04 21:02:13
Thread-2:17-02-04 21:02:15
退出主线程
由执行结果看到,程序正确得到了同步效果
❤️
网友评论