Python 线程同步变量,同步条件,列队

条件变量同步

有一类线程需要满足条件之后才能够继续执行,Python提供了threading.Condition 对象用于条件变量线程的支持,它除了能提供RLock()或Lock()的方法外,还提供了 wait()、notify()、notifyAll()方法。 lock_con=threading.Condition([Lock/Rlock]): 锁是可选选项,不传人锁,对象自动创建一个RLock()。

1wait():条件不满足时调用,线程会释放锁并进入等待阻塞; 2notify():条件创造后调用,通知等待池激活一个线程; 3notifyAll():条件创造后调用,通知等待池激活所有线程。 4 5 6import threading, time 7from random import randint 8 9class Producer(threading.Thread): 10 def run(self): 11 global L 12 while True: 13 val = randint(0, 100) 14 print('生产者', self.name, ':Append'+str(val),L) 15 if lock_con.acquire(): 16 L.append(val) 17 lock_con.notify() 18 lock_con.release() 19 time.sleep(3) 20 21class Consumer(threading.Thread): 22 def run(self): 23 global L 24 while True: 25 lock_con.acquire() 26 if len(L) == 0: 27 lock_con.wait() 28 print('消费者', self.name, ":Delete" + str(L[0]), L) 29 del L[0] 30 lock_con.release() 31 time.sleep(0.25) 32 33 34if __name__ == "__main__": 35 L = [] 36 lock_con = threading.Condition() 37 threads = [] 38 for i in range(5): 39 threads.append(Producer()) 40 threads.append(Consumer()) 41 for t in threads: 42 t.start() 43 for t in threads: 44 t.join() 45 print('---- end ----') 46 47#运行结果: 48生产者 Thread-1 :Append63 [] 49生产者 Thread-2 :Append66 [63] 50生产者 Thread-3 :Append20 [63, 66] 51生产者 Thread-4 :Append83 [63, 66, 20] 52生产者 Thread-5 :Append2 [63, 66, 20, 83] 53生产者 Thread-4 :Append26 [] 54消费者 Thread-6 :Delete26 [26] 55生产者 Thread-2 :Append21 [] 56生产者 Thread-3 :Append71 [21] 57生产者 Thread-1 :Append19 [21, 71] 58生产者 Thread-5 :Append100 [21, 71, 19] 59生产者 Thread-1 :Append96 [] 60消费者 Thread-6 :Delete96 [96] 61........ 62

同步条件

条件同步和条件变量同步差不多意思,只是少了锁功能,因为条件同步设计于不访问共享资源的条件环境。event=threading.Event():条件环境对象,初始值 为False;

1event.isSet():返回event的状态值; 2event.wait():如果 event.isSet()==False将阻塞线程; 3event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度; 4event.clear():恢复event的状态值为False。 5 6 7import threading, time 8 9class Boss(threading.Thread): 10 def run(self): 11 print("BOSS: 今晚大家加班") 12 event.isSet() or event.set() 13 time.sleep(5) 14 print("BOSS: 大家可以下班了") 15 event.isSet() or event.set() 16 17 18class Worker(threading.Thread): 19 def run(self): 20 event.wait() 21 print("Worker: 唉。。。。") 22 time.sleep(0.25) 23 event.clear() 24 event.wait() 25 print("Worker: Great!") 26 27 28if __name__ == "__main__": 29 event = threading.Event() 30 threads = [] 31 for i in range(5): 32 threads.append(Worker()) 33 threads.append(Boss()) 34 for t in threads: 35 t.start() 36 for t in threads: 37 t.join() 38 39#运行结果: 40BOSS: 今晚大家加班 41Worker: 唉。。。。 42Worker: 唉。。。。 43Worker: 唉。。。。 44Worker: 唉。。。。 45Worker: 唉。。。。 46BOSS: 大家可以下班了 47Worker: Great! 48Worker: Great! 49Worker: Great! 50Worker: Great! 51Worker: Great!

列队

1q = Queue.Queue(maxsize = 10) 创建一个“队列”对象。Queue.Queue类即是一个队列的同步实现。队列长度可为无限或者有限。可通过Queue的构造函数的可选参数maxsize来设定队列长度。如果maxsize小于1就表示队列长度无限。 2 3q.put()方法在队尾插入一个项目。put()有两个参数,第一个item为必需的,为插入项目的值;第二个block为可选参数,默认为1。如果队列当前为空且block为1,put()方法就使调用线程暂停,直到空出一个数据单元。如果block为0,put方法将引发Full异常。 4 5q.get([block[, timeout]])方法从队头删除并返回一个项目。可选参数为block,默认为True。如果队列为空且block为True,get()就使调用线程暂停,直至有项目可用。如果队列为空且block为False,队列将引发Empty异常,timeout等待时间。 6 7q.qsize() 返回队列的大小 8q.empty() 如果队列为空,返回True,反之False 9q.full() 如果队列满了,返回True,反之False 10q.full 与 maxsize 大小对应 11q.get_nowait() 相当q.get(False) 12q.put_nowait(item) 相当q.put(item, False) 13q.task_done() 在完成一项工作之后,q.task_done() 函数向任务已经完成的队列发送一个信号 14q.join() 实际上意味着等到队列为空,再执行别的操作 15 16 17import queue 18 19d = queue.Queue() 20 21d.put('1') 22d.put('2') 23d.put('3') 24 25print(d.get()) 26print(d.get()) 27print(d.get()) 28print(d.get()) 29print(d.get(0)) 30 31# 运行结果: 321 332 343 35报错: 36queue.Empty

线程操作列表是不安全的。

1import threading, time 2 3li = [1, 2, 3, 4, 5] 4 5def pri(): 6 while li: 7 a = li [-1] 8 print(a) 9 time.sleep(1) 10 try: 11 li.remove(a) 12 except: 13 print('-----', a) 14t1 = threading.Thread(target=pri, args=()) 15t1.start() 16t2 = threading.Thread(target=pri, args=()) 17t2.start() 18 19# 运行结果: 205 215 224 23----- 5 244 253 26----- 4 273 282 29----- 3 302 311 32----- 2 331 34----- 1 35 36 37import threading, queue 38from time import sleep 39from random import randint 40 41class Production(threading.Thread): 42 def run(self): 43 while True: 44 r = randint(0, 100) 45 q.put(r) 46 print("生产出来 %s 号包子" %r) 47 sleep(1) 48 49class Proces(threading.Thread): 50 def run(self): 51 while True: 52 re = q.get() 53 print('吃掉 %s号包子' %re) 54 55if __name__ == '__main__': 56 q = queue.Queue(10) 57 threads = [Production(),Production(),Production(),Proces()] 58 for t in threads: 59 t.start() 60 61# 运行结果: 62生产出来 94 号包子 63生产出来 13 号包子 64生产出来 79 号包子 65吃掉 94号包子 66吃掉 13号包子 67吃掉 79号包子 68生产出来 43 号包子 69吃掉 43号包子 70生产出来 32 号包子 71吃掉 32号包子 72......
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Python 线程同步变量,同步条件,列队 - HelloWorld