条件变量同步

有一类线程需要满足条件之后才能够继续执行,Python提供了threading.Condition 对象用于条件变量线程的支持,它除了能提供RLock()或Lock()的方法外,还提供了 wait()、notify()、notifyAll()方法。

lock_con=threading.Condition([Lock/Rlock]): 锁是可选选项,不传人锁,对象自动创建一个RLock()。

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

同步条件

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

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

列队

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

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

  1. import threading, time
  2. li = [1, 2, 3, 4, 5]
  3. def pri():
  4. while li:
  5. a = li [-1]
  6. print(a)
  7. time.sleep(1)
  8. try:
  9. li.remove(a)
  10. except:
  11. print('-----', a)
  12. t1 = threading.Thread(target=pri, args=())
  13. t1.start()
  14. t2 = threading.Thread(target=pri, args=())
  15. t2.start()
  16. # 运行结果:
  17. 5
  18. 5
  19. 4
  20. ----- 5
  21. 4
  22. 3
  23. ----- 4
  24. 3
  25. 2
  26. ----- 3
  27. 2
  28. 1
  29. ----- 2
  30. 1
  31. ----- 1
  1. import threading, queue
  2. from time import sleep
  3. from random import randint
  4. class Production(threading.Thread):
  5. def run(self):
  6. while True:
  7. r = randint(0, 100)
  8. q.put(r)
  9. print("生产出来 %s 号包子" %r)
  10. sleep(1)
  11. class Proces(threading.Thread):
  12. def run(self):
  13. while True:
  14. re = q.get()
  15. print('吃掉 %s号包子' %re)
  16. if __name__ == '__main__':
  17. q = queue.Queue(10)
  18. threads = [Production(),Production(),Production(),Proces()]
  19. for t in threads:
  20. t.start()
  21. # 运行结果:
  22. 生产出来 94 号包子
  23. 生产出来 13 号包子
  24. 生产出来 79 号包子
  25. 吃掉 94号包子
  26. 吃掉 13号包子
  27. 吃掉 79号包子
  28. 生产出来 43 号包子
  29. 吃掉 43号包子
  30. 生产出来 32 号包子
  31. 吃掉 32号包子
  32. ......

Python 线程同步变量,同步条件,列队的更多相关文章

  1. python线程中的同步问题

    多线程开发可能遇到的问题 假设两个线程t1和t2都要对num=0进行增1运算,t1和t2都各对num修改1000000次,num的最终的结果应该为2000000.但是由于是多线程访问,有可能出现下面情 ...

  2. python 线程之 数据同步 Queue

    Queue:将数据从一个线程发往另外一个线程比较通用的方式是使用queue模块的Queue类 1, 首先创建一个Queue模块的对象,创建Queue对象可以传递maxsize也可以不传递 2. 使用对 ...

  3. python初识,变量,条件判断语句,基本数据类型,while循环语句

    python文件后缀可以是任意,但是导入模块时不用.py后缀时会报错 python文件的两种执行方式: python解释器 python文件路径 进入python解释权,事实获取执行结果 在Linux ...

  4. Python学习---线程锁/信号量/条件变量同步/线程池1221

    线程锁 问题现象: 多线程情况下,CPU遇到阻塞会进行线程的切换,所以导致执行了tmp-=1的值还未赋值给num=tmp,另一个线程2又开始了tmp -=1,所以导致最后的值重复赋值给了num,所以出 ...

  5. 练习生产者与消费者-PYTHON多线程中的条件变量同步-Queue

    以前练习过,但好久不用,手生,概念也生了, 重温一下.. URL: http://www.cnblogs.com/holbrook/tag/%E5%A4%9A%E7%BA%BF%E7%A8%8B/ ~ ...

  6. PYTHON线程知识再研习E---条件变量同步Condition

    Python提供的Condition对象提供了对复杂线程同步问题的支持.Condition被称为条件变量,除了提供与Lock类似的 acquire和release方法外,还提供了wait和notify ...

  7. python多线程编程5: 条件变量同步-乾颐堂

    互斥锁是最简单的线程同步机制,Python提供的Condition对象提供了对复杂线程同步问题的支持.Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还 ...

  8. 27 python 初学(信号量、条件变量、同步条件、队列)

    参考博客: www.cnblogs.com/yuanchenqi/articles/5733873.html  semaphore 信号量: condition 条件变量: event 同步条件:条件 ...

  9. Linux 多线程条件变量同步

    条件变量是线程同步的另一种方式,实际上,条件变量是信号量的底层实现,这也就意味着,使用条件变量可以拥有更大的自由度,同时也就需要更加小心的进行同步操作.条件变量使用的条件本身是需要使用互斥量进行保护的 ...

随机推荐

  1. AddTransient,AddScope和AddSingleton 有什么不同?

    我们先来创建几个接口using System; namespace DependencyInjectionSample.Interfaces{ public interface IOperation ...

  2. 【牛客网71E】 组一组(差分约束,拆位)

    传送门 NowCoder Solution 考虑一下看到这种区间或与区间与的关系,拆一下位. 令\(s_i\)表示前缀和,则: 那么如果现在考虑到了第\(i\)为,有如下4种可能: \(opt=1\) ...

  3. cad.net 利用win32api实现不重复打开dwg路径的文件夹(资源管理器)

    这里地址的方法也是可用的,但是net3.5不能使用 为此我选择使用win32api的方式来遍历当前桌面所有资源管理器 /// <summary> /// 不重复打开dwg路径的资源管理器 ...

  4. 电子技术经典资料汇总:PCB设计篇

    电子技术经典资料汇总:PCB设计篇,下面的链接是一个一个的文件下载的,也是压缩包的内容,只不过我把他们给汇总成了一个压缩包,方便大家下载,还有更多电子技术必备基础资料,通信无线类的,C语言篇的,关于电 ...

  5. JavaScript实现HTML页面集成QQ空间分享功能

    <!DOCTYPE HTML> <html> <head> <title>QQ空间分享</title> <meta http-equi ...

  6. 使用 PLSQL 连接 Oracle9i 数据库

    昨天用了Navicate连接Oracle数据库,不停的掉线,然后死机,只能重启Navicate,没办法,还是用回plsql吧,重装了一遍(之前重装系统后,电脑自带的公司原有的软件没啦) 先安装了Ora ...

  7. 用react+redux写一个todo

    概述 最近学习redux,打算用redux写了一个todo.记录下来,供以后开发时参考,相信对其他人也有用. 代码 代码请见我的github 组织架构如下图:

  8. MySQL的时间、日期型

    MySQL的时间.日期型 MySQL中表示时间值的有DATE.时间类型为DATETIME.DATE.TIMESTAMP.TIME和YEAR.每个时间类型有一个有效值范围和一个"零" ...

  9. Python: Ubuntu 安装numpy,scipy,matplotlib

    安装python-dev 安装这个包,以后安装各种python扩展包,可以省很多事情. sudo apt-get install python-dev 使用apt-get 安装 只需要下面的几个命令即 ...

  10. Mac下命令行tree生成文件树

    不像Windows,Mac环境本身是没有tree命令的,但可以后天呐~ 1.下载文件包并将其放在系统目录下(本人存放路径为/Users/) https://homebrew.bintray.com/b ...