1. 21 interest=0.05
  2. 22 count=amount+amount*interest
  3. 23
  4. 24 self.withdraw(count)
  5. 25
  6. 26
  7. 27 def transfer(_from, to, amount):
  8. 28
  9. 29 #锁不可以加在这里 因为其他的线程执行的其它方法在不加锁的情况下数据同样是不安全的
  10. 30 _from.withdraw(amount)
  11. 31 to.deposit(amount)
  12. 32
  13. 33 alex = Account('alex',1000)
  14. 34 yuan = Account('yuan',1000)
  15. 35
  16. 36 t1=threading.Thread(target = transfer, args = (alex,yuan, 100))
  17. 37 t1.start()
  18. 38
  19. 39 t2=threading.Thread(target = transfer, args = (yuan,alex, 200))
  20. 40 t2.start()
  21. 41
  22. 42 t1.join()
  23. 43 t2.join()
  24. 44
  25. 45 print('>>>',alex.balance)
  26. 46 print('>>>',yuan.balance)

6.条件变量同步(Condition)

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

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

  1. wait():条件不满足时调用,线程会释放锁并进入等待阻塞;
  2. notify():条件创造后调用,通知等待池激活一个线程;
  3. notifyAll():条件创造后调用,通知等待池激活所有线程。

示例代码:

  1. 1 import threading,time
  2. 2 from random import randint
  3. 3 class Producer(threading.Thread):
  4. 4 def run(self):
  5. 5 global L
  6. 6 while True:
  7. 7 val=randint(0,100)
  8. 8 print('生产者',self.name,":Append"+str(val),L)
  9. 9 if lock_con.acquire():
  10. 10 L.append(val)
  11. 11 lock_con.notify()
  12. 12 lock_con.release()
  13. 13 time.sleep(3)
  14. 14 class Consumer(threading.Thread):
  15. 15 def run(self):
  16. 16 global L
  17. 17 while True:
  18. 18 lock_con.acquire()
  19. 19 if len(L)==0:
  20. 20 lock_con.wait()
  21. 21 print('消费者',self.name,":Delete"+str(L[0]),L)
  22. 22 del L[0]
  23. 23 lock_con.release()
  24. 24 time.sleep(0.25)
  25. 25
  26. 26 if __name__=="__main__":
  27. 27
  28. 28 L=[]
  29. 29 lock_con=threading.Condition()
  30. 30 threads=[]
  31. 31 for i in range(5):
  32. 32 threads.append(Producer())
  33. 33 threads.append(Consumer())
  34. 34 for t in threads:
  35. 35 t.start()
  36. 36 for t in threads:
  37. 37 t.join()

7.同步条件(Event)

条件同步和条件变量同步差不多意思,只是少了锁功能,因为条件同步设计于不访问共享资源的条件环境。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:

  1. 1 import threading,time
  2. 2 class Boss(threading.Thread):
  3. 3 def run(self):
  4. 4 print("BOSS:今晚大家都要加班到22:00。")
  5. 5 event.isSet() or event.set()
  6. 6 time.sleep(5)
  7. 7 print("BOSS:<22:00>可以下班了。")
  8. 8 event.isSet() or event.set()
  9. 9 class Worker(threading.Thread):
  10. 10 def run(self):
  11. 11 event.wait()
  12. 12 print("Worker:哎……命苦啊!")
  13. 13 time.sleep(0.25)
  14. 14 event.clear()
  15. 15 event.wait()
  16. 16 print("Worker:OhYeah!")
  17. 17 if __name__=="__main__":
  18. 18 event=threading.Event()
  19. 19 threads=[]
  20. 20 for i in range(5):
  21. 21 threads.append(Worker())
  22. 22 threads.append(Boss())
  23. 23 for t in threads:
  24. 24 t.start()
  25. 25 for t in threads:
  26. 26 t.join()

例子2:

  1. 1 import threading,time
  2. 2 import random
  3. 3 def light():
  4. 4 if not event.isSet():
  5. 5 event.set() #wait就不阻塞 #绿灯状态
  6. 6 count = 0
  7. 7 while True:
  8. 8 if count < 10:
  9. 9 print('\033[42;1m--green light on---\033[0m')
  10. 10 elif count <13:
  11. 11 print('\033[43;1m--yellow light on---\033[0m')
  12. 12 elif count <20:
  13. 13 if event.isSet():
  14. 14 event.clear()
  15. 15 print('\033[41;1m--red light on---\033[0m')
  16. 16 else:
  17. 17 count = 0
  18. 18 event.set() #打开绿灯
  19. 19 time.sleep(1)
  20. 20 count +=1
  21. 21 def car(n):
  22. 22 while 1:
  23. 23 time.sleep(random.randrange(10))
  24. 24 if event.isSet(): #绿灯
  25. 25 print("car [%s] is running.." % n)
  26. 26 else:
  27. 27 print("car [%s] is waiting for the red light.." %n)
  28. 28 if __name__ == '__main__':
  29. 29 event = threading.Event()
  30. 30 Light = threading.Thread(target=light)
  31. 31 Light.start()
  32. 32 for i in range(3):
  33. 33 t = threading.Thread(target=car,args=(i,))
  34. 34 t.start()

8.信号量

信号量用来控制线程并发数的,BoundedSemaphore或Semaphore管理一个内置的计数 器,每当调用acquire()时-1,调用release()时+1。

计数器不能小于0,当计数器为 0时,acquire()将阻塞线程至同步锁定状态,直到其他线程调用release()。(类似于停车位的概念)

BoundedSemaphore与Semaphore的唯一区别在于前者将在调用release()时检查计数 器的值是否超过了计数器的初始值,如果超过了将抛出一个异常。

例子:

  1. 1 import threading,time
  2. 2 class myThread(threading.Thread):
  3. 3 def run(self):
  4. 4 if semaphore.acquire():
  5. 5 print(self.name)
  6. 6 time.sleep(5)
  7. 7 semaphore.release()
  8. 8 if __name__=="__main__":
  9. 9 semaphore=threading.Semaphore(5)
  10. 10 thrs=[]
  11. 11 for i in range(100):
  12. 12 thrs.append(myThread())
  13. 13 for t in thrs:
  14. 14 t.start()

9.队列Queue

使用队列方法:

  1. 1 创建一个“队列”对象
  2. 2 import Queue
  3. 3 q = Queue.Queue(maxsize = 10)
  4. 4 Queue.Queue类即是一个队列的同步实现。队列长度可为无限或者有限。可通过Queue的构造函数的可选参数maxsize来设定队列长度。如果maxsize小于1就表示队列长度无限。
  5. 5
  6. 6 将一个值放入队列中
  7. 7 q.put(10)
  8. 8 调用队列对象的put()方法在队尾插入一个项目。put()有两个参数,第一个item为必需的,为插入项目的值;第二个block为可选参数,默认为
  9. 9 1。如果队列当前为空且block1put()方法就使调用线程暂停,直到空出一个数据单元。如果block0put方法将引发Full异常。
  10. 10
  11. 11 将一个值从队列中取出
  12. 12 q.get()
  13. 13 调用队列对象的get()方法从队头删除并返回一个项目。可选参数为block,默认为True。如果队列为空且blockTrueget()就使调用线程暂停,直至有项目可用。如果队列为空且blockFalse,队列将引发Empty异常。
  14. 14
  15. 15 Python Queue模块有三种队列及构造函数:
  16. 16 1Python Queue模块的FIFO队列先进先出。 class queue.Queue(maxsize)
  17. 17 2LIFO类似于堆,即先进后出。 class queue.LifoQueue(maxsize)
  18. 18 3、还有一种是优先级队列级别越低越先出来。 class queue.PriorityQueue(maxsize)
  19. 19
  20. 20 此包中的常用方法(q = Queue.Queue()):
  21. 21 q.qsize() 返回队列的大小
  22. 22 q.empty() 如果队列为空,返回True,反之False
  23. 23 q.full() 如果队列满了,返回True,反之False
  24. 24 q.full maxsize 大小对应
  25. 25 q.get([block[, timeout]]) 获取队列,timeout等待时间
  26. 26 q.get_nowait() 相当q.get(False)
  27. 27 非阻塞 q.put(item) 写入队列,timeout等待时间
  28. 28 q.put_nowait(item) 相当q.put(item, False)
  29. 29 q.task_done() 在完成一项工作之后,q.task_done() 函数向任务已经完成的队列发送一个信号
  30. 30 q.join() 实际上意味着等到队列为空,再执行别的操作

例子集合:

  1. 1 #例子1:
  2. 2 import threading,queue
  3. 3 from time import sleep
  4. 4 from random import randint
  5. 5 class Production(threading.Thread):
  6. 6 def run(self):
  7. 7 while True:
  8. 8 r=randint(0,100)
  9. 9 q.put(r)
  10. 10 print("生产出来%s号包子"%r)
  11. 11 sleep(1)
  12. 12 class Proces(threading.Thread):
  13. 13 def run(self):
  14. 14 while True:
  15. 15 re=q.get()
  16. 16 print("吃掉%s号包子"%re)
  17. 17 if __name__=="__main__":
  18. 18 q=queue.Queue(10)
  19. 19 threads=[Production(),Production(),Production(),Proces()]
  20. 20 for t in threads:
  21. 21 t.start()
  22. 22
  23. 23 #例子2
  24. 24 import time,random
  25. 25 import queue,threading
  26. 26 q = queue.Queue()
  27. 27 def Producer(name):
  28. 28 count = 0
  29. 29 while count <20:
  30. 30 time.sleep(random.randrange(3))
  31. 31 q.put(count)
  32. 32 print('Producer %s has produced %s baozi..' %(name, count))
  33. 33 count +=1
  34. 34 def Consumer(name):
  35. 35 count = 0
  36. 36 while count <20:
  37. 37 time.sleep(random.randrange(4))
  38. 38 if not q.empty():
  39. 39 data = q.get()
  40. 40 print(data)
  41. 41 print('\033[32;1mConsumer %s has eat %s baozi...\033[0m' %(name, data))
  42. 42 else:
  43. 43 print("-----no baozi anymore----")
  44. 44 count +=1
  45. 45 p1 = threading.Thread(target=Producer, args=('A',))
  46. 46 c1 = threading.Thread(target=Consumer, args=('B',))
  47. 47 p1.start()
  48. 48 c1.start()
  49. 49
  50. 50 #例子3
  51. 51 #实现一个线程不断生成一个随机数到一个队列中(考虑使用Queue这个模块)
  52. 52 # 实现一个线程从上面的队列里面不断的取出奇数
  53. 53 # 实现另外一个线程从上面的队列里面不断取出偶数
  54. 54
  55. 55 import random,threading,time
  56. 56 from queue import Queue
  57. 57 #Producer thread
  58. 58 class Producer(threading.Thread):
  59. 59 def __init__(self, t_name, queue):
  60. 60 threading.Thread.__init__(self,name=t_name)
  61. 61 self.data=queue
  62. 62 def run(self):
  63. 63 for i in range(10): #随机产生10个数字 ,可以修改为任意大小
  64. 64 randomnum=random.randint(1,99)
  65. 65 print ("%s: %s is producing %d to the queue!" % (time.ctime(), self.getName(), randomnum))
  66. 66 self.data.put(randomnum) #将数据依次存入队列
  67. 67 time.sleep(1)
  68. 68 print ("%s: %s finished!" %(time.ctime(), self.getName()))
  69. 69
  70. 70 #Consumer thread
  71. 71 class Consumer_even(threading.Thread):
  72. 72 def __init__(self,t_name,queue):
  73. 73 threading.Thread.__init__(self,name=t_name)
  74. 74 self.data=queue
  75. 75 def run(self):
  76. 76 while 1:
  77. 77 try:
  78. 78 val_even = self.data.get(1,5) #get(self, block=True, timeout=None) ,1就是阻塞等待,5是超时5秒
  79. 79 if val_even%2==0:
  80. 80 print ("%s: %s is consuming. %d in the queue is consumed!" % (time.ctime(),self.getName(),val_even))
  81. 81 time.sleep(2)
  82. 82 else:
  83. 83 self.data.put(val_even)
  84. 84 time.sleep(2)
  85. 85 except: #等待输入,超过5秒 就报异常
  86. 86 print ("%s: %s finished!" %(time.ctime(),self.getName()))
  87. 87 break
  88. 88 class Consumer_odd(threading.Thread):
  89. 89 def __init__(self,t_name,queue):
  90. 90 threading.Thread.__init__(self, name=t_name)
  91. 91 self.data=queue
  92. 92 def run(self):
  93. 93 while 1:
  94. 94 try:
  95. 95 val_odd = self.data.get(1,5)
  96. 96 if val_odd%2!=0:
  97. 97 print ("%s: %s is consuming. %d in the queue is consumed!" % (time.ctime(), self.getName(), val_odd))
  98. 98 time.sleep(2)
  99. 99 else:
  100. 100 self.data.put(val_odd)
  101. 101 time.sleep(2)
  102. 102 except:
  103. 103 print ("%s: %s finished!" % (time.ctime(), self.getName()))
  104. 104 break
  105. 105 #Main thread
  106. 106 def main():
  107. 107 queue = Queue()
  108. 108 producer = Producer('Pro.', queue)
  109. 109 consumer_even = Consumer_even('Con_even.', queue)
  110. 110 consumer_odd = Consumer_odd('Con_odd.',queue)
  111. 111 producer.start()
  112. 112 consumer_even.start()
  113. 113 consumer_odd.start()
  114. 114 producer.join()
  115. 115 consumer_even.join()
  116. 116 consumer_odd.join()
  117. 117 print ('All threads terminate!')
  118. 118
  119. 119 if __name__ == '__main__':
  120. 120 main()
  121. 121
  122. 122 #注意:列表是线程不安全的
  123. 123 #例子4
  124. 124 import threading,time
  125. 125
  126. 126 li=[1,2,3,4,5]
  127. 127
  128. 128 def pri():
  129. 129 while li:
  130. 130 a=li[-1]
  131. 131 print(a)
  132. 132 time.sleep(1)
  133. 133 try:
  134. 134 li.remove(a)
  135. 135 except:
  136. 136 print('----',a)
  137. 137
  138. 138 t1=threading.Thread(target=pri,args=())
  139. 139 t1.start()

  1. t2=threading.Thread(target=pri,args=())
  2. t2.start()
 
分类: python高级

第七篇: python高级之多线程的更多相关文章

  1. python高级之多线程

    python高级之多线程 本节内容 线程与进程定义及区别 python全局解释器锁 线程的定义及使用 互斥锁 线程死锁和递归锁 条件变量同步(Condition) 同步条件(Event) 信号量 队列 ...

  2. 第十章:Python高级编程-多线程、多进程和线程池编程

    第十章:Python高级编程-多线程.多进程和线程池编程 Python3高级核心技术97讲 笔记 目录 第十章:Python高级编程-多线程.多进程和线程池编程 10.1 Python中的GIL 10 ...

  3. Python高级编程-多线程

    (一)进程线程概述: 很多同学都听说过,现代操作系统比如Mac OS X,UNIX,Linux,Windows等,都是支持“多任务”的操作系统. 什么叫“多任务”呢?简单地说,就是操作系统可以同时运行 ...

  4. 【Python之路】第七篇--Python基础之面向对象及相关

    面向对象基础 基础内容介绍详见一下两篇博文: 面向对象初级篇 面向对象进阶篇 其他相关 一.isinstance(obj, cls) 检查obj是否是类 cls 的对象 class Foo(objec ...

  5. 第七篇 python基础之函数,递归,内置函数

    一 数学定义的函数与python中的函数 初中数学函数定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因 ...

  6. 爬虫篇-python爬虫中多线程的使用

    queue介绍 queue是python的标准库,俗称队列.可以直接import引用,在python2.x中,模块名为Queue.python3直接queue即可 在python中,多个线程之间的数据 ...

  7. Python之路(第七篇)Python作用域、匿名函数、函数式编程、map函数、filter函数、reduce函数

    一.作用域 return 可以返回任意值例子 def test1(): print("test1") def test(): print("test") ret ...

  8. 第七篇 Python面向对象

    类是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用,特征被称为属性,行为被称为方法,类就相当于制造飞机时的图纸,是一个模板,是负责创建对象的. 对象是由类创建出来的一个具体存在,可 ...

  9. 第七篇Python基本数据类型之数字&字符串&布尔值

    数字 写在最前,必须要会的:int() 整型 Python3里无论数字多长都用int表示,Python2里有int和Long表示,Long表示长整型 有关数字的常用方法,方法调用后面都必须带括号() ...

随机推荐

  1. deep learning framework(不同的深度学习框架)

    常用的deep learning frameworks 基本转自:http://www.codeceo.com/article/10-open-source-framework.html 1. Caf ...

  2. [BZOJ 2186] [Sdoi2008] 沙拉公主的困惑 【欧拉函数】

    题目链接:BZOJ - 2186 题目分析 题目要求出 [1, n!] 中有多少数与 m! 互质.(m <= n) 那么在 [1, m!] 中有 phi(m!) 个数与 m! 互质,如果一个数 ...

  3. [BZOJ 1016] [JSOI2008] 最小生成树计数 【DFS】

    题目链接:BZOJ - 1016 题目分析 最小生成树的两个性质: 同一个图的最小生成树,满足: 1)同一种权值的边的个数相等 2)用Kruscal按照从小到大,处理完某一种权值的所有边后,图的连通性 ...

  4. 浅谈JS DDoS攻击原理与防御

    分布式拒绝服务攻击(DDoS)攻击是一种针对网站发起的最古老最普遍的攻击.Nick Sullivan是网站加速和安全服务提供商CloudFlare的一名系统工程师.近日,他撰文介绍了攻击者如何利用恶意 ...

  5. 【HTTP】HTTP access control (CORS)

    https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS Cross-site HTTP requests are H ...

  6. LeetCode_3 sum closet

    Given an array S of n integers, find three integers in S such that the sum is closest to a given num ...

  7. java中基本类型封装对象所占内存的大小(转)

    这是一个程序,java中没有现成的sizeof的实现,原因主要是java中的基本数据类型的大小都是固定的,所以看上去没有必要用sizeof这个关键字. 实现的想法是这样的:java.lang.Runt ...

  8. Spark MLBase分布式机器学习系统入门:以MLlib实现Kmeans聚类算法

    1.什么是MLBaseMLBase是Spark生态圈的一部分,专注于机器学习,包含三个组件:MLlib.MLI.ML Optimizer. ML Optimizer: This layer aims ...

  9. tomcat 系统架构与设计模式 第二部分 设计模式 转

    Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析 许 令波, Java 开发工程师, 淘宝网 许令波,现就职于淘宝网,是一名 Java 开发工程师.对大型互联网架构设计颇感兴趣,并对一些 ...

  10. asp.net中水印的实现代码

    水印是为了防止别盗用我们的图片. 两种方式实现水印效果 1)可以在用户上传时添加水印. a)   好处:与2种方法相比,用户每次读取此图片时,服务器直接发送给客户就行了. b)   缺点:破坏了原始图 ...