这篇文章给大家分享的是有关Python实现线程间同步的方法的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。

线程间同步

如果多个线程共同对某个数据修改,则可能出现不可预料的结果,为了保证数据的正确性,需要对多个线程进行同步。

使用Thread对象的Lock和Rlock可以实现简单的线程同步,这两个对象都有acquire方法和release方法,对于那些需要每次只允许一个线程操作的数据,可以将其操作放到acquire和release方法之间。

需要注意的是,Python有一个GIL(Global Interpreter Lock)机制,任何线程在运行之前必须获取这个全局锁才能执行,每当执行完100条字节码,全局锁才会释放,切换到其他线程执行。

线程同步问题

多线程实现同步有四种方式:

锁机制,信号量,条件判断和同步队列。

下面我主要关注两种同步机制:锁机制和同步队列。

(1)锁机制

threading的Lock类,用该类的acquire函数进行加锁,用realease函数进行解锁

importthreadingimporttimeclassmyThread(threading.Thread):def__init__(self,threadID,name,counter):threading.Thread.__init__(self)self.threadID=threadIDself.name=nameself.counter=counterdefrun(self):print("Starting"+self.name)#获得锁,成功获得锁定后返回True#可选的timeout参数不填时将一直阻塞直到获得锁定#否则超时后将返回FalsethreadLock.acquire()print_time(self.name,self.counter,5)#释放锁threadLock.release()defprint_time(threadName,delay,counter):whilecounter:time.sleep(delay)print("%s:%s"%(threadName,time.ctime(time.time())))counter-=1threadLock=threading.Lock()threads=[]#创建新线程thread1=myThread(1,"Thread-1",1)thread2=myThread(2,"Thread-2",2)#开启新线程thread1.start()thread2.start()#添加线程到线程列表threads.append(thread1)threads.append(thread2)#等待所有线程完成fortinthreads:t.join()print("ExitingMainThread")

(2) 线程同步队列queue

python2.x中提供的Queue, Python3.x中提供的是queue

见import queue.

Python的queue模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列PriorityQueue。这些队列都实现了锁原语,能够在多线程中直接使用。可以使用队列来实现线程间的同步。

queue模块中的常用方法:

queue.qsize() 返回队列的大小

queue.empty() 如果队列为空,返回True,反之False

queue.full() 如果队列满了,返回True,反之False

queue.full 与 maxsize 大小对应

queue.get([block[, timeout]])获取队列,timeout等待时间

queue.get_nowait() 相当Queue.get(False)

queue.put(item) 写入队列,timeout等待时间

queue.put_nowait(item) 相当Queue.put(item, False)

queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号

queue.join() 实际上意味着等到队列为空,再执行别的操作

案例1:

importqueueimportthreadingimporttimeexitFlag=0classmyThread(threading.Thread):def__init__(self,threadID,name,q):threading.Thread.__init__(self)self.threadID=threadIDself.name=nameself.q=qdefrun(self):print("Starting"+self.name)process_data(self.name,self.q)print("Exiting"+self.name)defprocess_data(threadName,q):whilenotexitFlag:queueLock.acquire()ifnotworkQueue.empty():data=q.get()queueLock.release()print("%sprocessing%s"%(threadName,data))else:queueLock.release()time.sleep(1)threadList=["Thread-1","Thread-2","Thread-3"]nameList=["One","Two","Three","Four","Five"]queueLock=threading.Lock()workQueue=queue.Queue(10)threads=[]threadID=1#创建新线程fortNameinthreadList:thread=myThread(threadID,tName,workQueue)thread.start()threads.append(thread)threadID+=1#填充队列queueLock.acquire()forwordinnameList:workQueue.put(word)queueLock.release()#等待队列清空whilenotworkQueue.empty():pass#通知线程是时候退出exitFlag=1#等待所有线程完成fortinthreads:t.join()print("ExitingMainThread")

案例2:

importtimeimportthreadingimportqueueclassWorker(threading.Thread):def__init__(self,name,queue):threading.Thread.__init__(self)self.queue=queueself.start()#执行run()defrun(self):#循环,保证接着跑下一个任务whileTrue:#队列为空则退出线程ifself.queue.empty():break#获取一个队列数据foo=self.queue.get()#延时1S模拟你要做的事情time.sleep(1)#打印print(self.getName()+"process"+str(foo))#任务完成self.queue.task_done()#队列queue=queue.Queue()#加入100个任务队列foriinrange(100):queue.put(i)#开10个线程foriinrange(10):threadName='Thread'+str(i)Worker(threadName,queue)#所有线程执行完毕后关闭queue.join()

感谢各位的阅读!关于Python实现线程间同步的方法就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到吧!