一丶锁

  线程安全:

    线程安全能够保证多个线程同时执行时程序依旧运行正确, 而且要保证对于共享的数据,可以由多个线程存取,但是同一时刻只能有一个线程进行存取.

  1. import threading
  2.  
  3. v = []
  4. def func(arg):
  5. v.append(arg) # 线程安全
  6. print(v)
  7. for i in range(10):
  8. t =threading.Thread(target=func,args=(i,))
  9. t.start()

线程安全

  1.GIL锁

    GIL锁中文名称为"全局解释器锁",主要体现在多线程中,每个线程在执行的过程中都需要先获取GIL,保证同一时刻只有一个线程可以执行代码.而Python语言和GIL没有半毛钱关系,仅仅是由于历史原因在Cpython虚拟机(解释器),难以移除GIL

    补充:

      (线程释放GIL锁的情况)在IO操作等可能会引起阻塞的system call之前,可以暂时释放GIL,但在执行完毕后,必须重新获取GIL. Python 3.x使用计时器(执行时间达到阈值后,当前线程释放GIL)或Python 2.x,tickets计数达到100,多线程爬取比单线程性能有所提升,因为遇到IO阻塞会自动释放GIL锁.

  2.Lock锁(一次放一个)

  1. import threading
  2. import time
  3.  
  4. v = []
  5. lock = threading.Lock()
  6.  
  7. def func(arg):
  8. lock.acquire() #加锁
  9. # ++++++++++++++++++被锁的功能
  10. v.append(arg)
  11. time.sleep(0.01)
  12. m = v[-1]
  13. print(arg,m)
  14. #+++++++++++++++++++
  15. lock.release() #解锁
  16.  
  17. for i in range(10):
  18. t =threading.Thread(target=func,args=(i,))
  19. t.start()
  20.  
  21. # 不加锁: #加锁后
  22. # 2 9 0 0
  23. # 3 9 1 1
  24. # 0 9 2 2
  25. # 1 9 3 3
  26. # 7 9 4 4
  27. # 5 9 5 5

Lock

  3.RLock锁(一次放一个)

  1. import threading
  2. import time
  3.  
  4. v = []
  5. lock = threading.RLock()
  6. def func(arg):
  7. lock.acquire()
  8. lock.acquire()
  9.  
  10. v.append(arg)
  11. time.sleep(0.01)
  12. m = v[-1]
  13. print(arg,m)
  14.  
  15. lock.release()
  16. lock.release()
  17.  
  18. for i in range(10):
  19. t =threading.Thread(target=func,args=(i,))
  20. t.start()
  21.  
  22. # 结果:
  23. # 0 0
  24. # 1 1
  25. # 2 2
  26. # 3 3
  27. # 4 4
  28. # 5 5

RLock

  Lock和RLock 的区别:

    Lock:Lock(指令锁)是可用的最低级别的同步指令.Lock处于锁定状态时,不被特定的线程拥有.Lock包含两种状态--锁定和非锁定,以及两个基本方法.可以认为Lock有一个锁定值池,当线程请求锁定时,将线程至于池中,知道获得锁定后出池.池中的线程处于状态图中的同步阻塞状态.

  RLock(可重入锁)是一个可以被同一个线程请求多次的同步指令.RLock使用了"拥有的线程"和"递归等级"的概念,处于锁定状态时,RLock被某个线程拥有.拥有RLock的线程可以再次调用acquire(),释放锁时需要调用release()相同次数.可以认为RLock包含一个锁定池和一个初始值为0的计数器,每次成功调用acquire()/release(),计数器将+1/-1,为0时锁处于未锁定状态

  简言之: Lock属于全局,Rlock属于线程

  4.BoundedSemaphore(一次放指定个数)

  1. import time
  2. import threading
  3.  
  4. lock = threading.BoundedSemaphore(4) #每次允许通过的个数
  5. def func(arg):
  6. lock.acquire() #加锁
  7. print(arg)
  8. time.sleep(2)
  9. lock.release() #解锁
  10.  
  11. for i in range(10):
  12. t =threading.Thread(target=func,args=(i,))
  13. t.start()

BoundedSemaphore

  5.Condition(一次放多个)

  1. import time
  2. import threading
  3.  
  4. lock = threading.Condition()
  5.  
  6. # ############## 方式一:输入几个取出来几个 ##############
  7.  
  8. def func(arg):
  9. print('线程进来了')
  10. lock.acquire()
  11. lock.wait() # 加锁
  12.  
  13. print(arg)
  14. time.sleep(1)
  15.  
  16. lock.release() #解锁
  17.  
  18. for i in range(10):
  19. t =threading.Thread(target=func,args=(i,))
  20. t.start()
  21.  
  22. while True:
  23. inp = int(input('>>>'))
  24.  
  25. lock.acquire()
  26. lock.notify(inp)
  27. lock.release()
  28.  
  29. #结果:
  30. # 线程进来了
  31. # ....
  32. # 线程进来了
  33. # >>>3
  34. # >>>0
  35. #
  36. #
  37. #
  38. # >>>3
  39. #
  40. #
  41. # >>>5
  42. #
  43. #
  44. #
  45. #
  46. # >>>9
  47.  
  48. # ############## 方式二(输入一次放一个)##############
  49. #
  50.  
  51. def xxxx():
  52. print('来执行函数了')
  53. input(">>>")
  54. # ct = threading.current_thread() # 获取当前线程
  55. # ct.getName()
  56. return True
  57.  
  58. def func(arg):
  59. print('线程进来了')
  60. lock.wait_for(xxxx)
  61. print(arg)
  62. time.sleep(1)
  63.  
  64. for i in range(10):
  65. t =threading.Thread(target=func,args=(i,))
  66. t.start()
  67.  
  68. #结果
  69. # >> > 线程进来了
  70. # 来执行函数了
  71. # >> > 线程进来了
  72. # 来执行函数了
  73. # >> > 1
  74. #
  75. #
  76. #
  77. #
  78. #
  79. #

Condition

  6.Event(一次放所有)

  1. import threading
  2.  
  3. lock = threading.Event()
  4.  
  5. def func(arg):
  6. print('线程来了')
  7. lock.wait() # 加锁:红灯
  8. print(arg)
  9.  
  10. for i in range(10):
  11. t =threading.Thread(target=func,args=(i,))
  12. t.start()
  13.  
  14. input(">>>>")
  15. lock.set() # 绿灯 获取
  16.  
  17. lock.clear() # 再次变红灯
  18.  
  19. for i in range(10):
  20. t =threading.Thread(target=func,args=(i,))
  21. t.start()
  22.  
  23. input(">>>>")
  24. lock.set() #绿灯 获取

Event

二丶threading.local

  作用:内部自动为每一个线程维护一个空间(字典),用于当前存取属于自己的值.保证线程之间的数据隔离

  {

  线程ID: {.....}

  线程ID: {.....}

  线程ID: {.....}

}

  1. import time
  2. import threading
  3.  
  4. DATA_DICT = {}
  5.  
  6. def func(arg):
  7. ident = threading.get_ident() #获取线程ID
  8. DATA_DICT[ident] = arg #{1756: 0, 2636: 1, 8892: 2, 8448: 3, 2344: 4, 7196: 5, 8572: 6, 2268: 7, 2480: 8, 7644: 9}
  9. time.sleep(1)
  10. print(DATA_DICT[ident],arg)
  11.  
  12. for i in range(10):
  13. t =threading.Thread(target=func,args=(i,))
  14. t.start()
  1. import time
  2. import threading
  3. INFO = {}
  4. class Local(object):
  5.  
  6. def __getattr__(self, item):
  7. ident = threading.get_ident()
  8. return INFO[ident][item]
  9.  
  10. def __setattr__(self, key, value):
  11. ident = threading.get_ident()
  12. if ident in INFO:
  13. INFO[ident][key] = value
  14. else:
  15. INFO[ident] = {key:value}
  16.  
  17. obj = Local()
  18.  
  19. def func(arg):
  20. obj.phone = arg # 调用对象的 __setattr__方法(“phone”,1)
  21. time.sleep(2)
  22. print(obj.phone,arg)
  23.  
  24. for i in range(10):
  25. t =threading.Thread(target=func,args=(i,))
  26. t.start()
  27. print(INFO)#{7688: {'phone': 0}, 8972: {'phone': 1}, 5280: {'phone': 2}, 4724: {'phone': 3},
  28. # 8384: {'phone': 4}, 8680: {'phone': 5}, 8220: {'phone': 6}, 9032: {'phone': 7}, 4660: {'phone': 8},
  29. # 528: {'phone': 9}}

三丶线程池 threadpool模块

  可以模拟一个场景,假如我们要去领签名照,在工作室签名的明星只有两个在哪儿,而要领签名照的人很多很多,我们可以创建一个大纸箱子,把那些想要领签名照的人的信息记录下来,然后等明星按顺序来签名.这个大纸箱子就是我们所谓的线程池,存放一个个的需求等待CPU来调度

  1. from concurrent.futures import ThreadPoolExecutor
  2. import time
  3.  
  4. def task(a1,a2):
  5. time.sleep(2)
  6. print(a1,a2)
  7.  
  8. # 创建了一个线程池(最多5个线程)
  9. pool = ThreadPoolExecutor(5)
  10.  
  11. for i in range(40):
  12. # 去线程池中申请一个线程,让线程执行task函数。
  13. pool.submit(task,i,8)
  1. import time
  2. import threading
  3.  
  4. def task(arg):
  5. time.sleep(50)
  6.  
  7. while True:
  8. num = input('>>>')
  9. t = threading.Thread(target=task,args=(num,))
  10. t.start()

线程

  1. import time
  2. from concurrent.futures import ThreadPoolExecutor
  3.  
  4. def task(arg):
  5. time.sleep(10)
  6. print("========")
  7.  
  8. pool = ThreadPoolExecutor(3)
  9. while True:
  10. num = input('>>>')
  11. pool.submit(task,num)

线程池

四丶生产者消费者模型

  所谓生产者消费者模型就是生产者跟消费者的关系而已,就像厨师跟顾客一样,只有厨师做出来饭,顾客才能吃,如果厨师做不出来饭,顾客想吃也吃不到,只能排队等

  1. import time
  2. import queue
  3. import threading
  4. q = queue.Queue() # 线程安全
  5.  
  6. def producer(id):
  7. """
  8. 生产者
  9. :return:
  10. """
  11. while True:
  12. time.sleep(2)
  13. q.put('包子')
  14. print('厨师%s 生产了一个包子' %id )
  15.  
  16. for i in range(1,4):
  17. t = threading.Thread(target=producer,args=(i,))
  18. t.start()
  19.  
  20. def consumer(id):
  21. """
  22. 消费者
  23. :return:
  24. """
  25. while True:
  26. time.sleep(1)
  27. v1 = q.get()
  28. print('顾客 %s 吃了一个包子' % id)
  29.  
  30. for i in range(1,3):
  31. t = threading.Thread(target=consumer,args=(i,))
  32. t.start()

    

锁丶threading.local丶线程池丶生产者消费者模型的更多相关文章

  1. 线程锁、threading.local(flask源码中用的到)、线程池、生产者消费者模型

    一.线程锁 线程安全,多线程操作时,内部会让所有线程排队处理.如:list/dict/Queue 线程不安全 + 人(锁) => 排队处理 1.RLock/Lock:一次放一个 a.创建10个线 ...

  2. 锁、threading.local、线程池

    一.锁 Lock(1次放1个) 什么时候用到锁: 线程安全,多线程操作时,内部会让所有线程排队处理.如:list.dict.queue 线程不安全, import threading import t ...

  3. threading.local()方法;线程池

    一,threading.local() import time import threading v = threading.local() def func(arg): # 内部会为当前线程创建一个 ...

  4. 进程同步控制(锁,信号量,事件), 进程通讯(队列和管道,生产者消费者模型) 数据共享(进程池和mutiprocess.Pool模块)

    参考博客 https://www.cnblogs.com/xiao987334176/p/9025072.html#autoid-1-1-0 进程同步(multiprocess.Lock.Semaph ...

  5. 4、网络并发编程--僵尸进程、孤儿进程、守护进程、互斥锁、消息队列、IPC机制、生产者消费者模型、线程理论与实操

    昨日内容回顾 操作系统发展史 1.穿孔卡片 CPU利用率极低 2.联机批处理系统 CPU效率有所提升 3.脱机批处理系统 CPU效率极大提升(现代计算机雏形) 多道技术(单核CPU) 串行:多个任务依 ...

  6. python并发编程之多进程(二):互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型

    一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...

  7. Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁、信号量、事件、队列、生产者消费者模型

    一.进程锁(同步锁/互斥锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 例 ...

  8. python开发进程:互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型

    一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...

  9. java多线程:线程间通信——生产者消费者模型

    一.背景 && 定义 多线程环境下,只要有并发问题,就要保证数据的安全性,一般指的是通过 synchronized 来进行同步. 另一个问题是,多个线程之间如何协作呢? 我们看一个仓库 ...

  10. 基于线程实现的生产者消费者模型(Object.wait(),Object.notify()方法)

    需求背景 利用线程来模拟生产者和消费者模型 系统建模 这个系统涉及到三个角色,生产者,消费者,任务队列,三个角色之间的关系非常简单,生产者和消费者拥有一个任务队列的引用,生产者负责往队列中放置对象(i ...

随机推荐

  1. Ajax 执行流程 有用 一点

    l 1.1使用JavaScript获得浏览器内置的AJAX引擎(XMLHttpRequest对象) l 1.2 通过AJAX引擎确定请求路径和请求参数 l 1.3 通知AJAX引擎发送请求 l AJA ...

  2. unreal3启动地图设置

    在defaultengine.ini中[URL]节: Map=MOBATinyMap.udkLocalMap=MOBATinyMap.udk 这里有Map和LocalMap两个属性,让人有点混淆,只好 ...

  3. 8、SRR数据下载https://ftp-trace.ncbi.nlm.nih.gov/sra/sdk/2.8.2/

    1.prefetch SRRxxxxxx         -/ncbi/public/sra 2.fastq-dump --split-files xxxxxxsra 3.SRA.SAM以及Fastq ...

  4. ASE分析

    1.Prepare necessary input files(可以参考上次的博客http://www.cnblogs.com/renping/p/7391028.html) 1)对fq1和fq2合并 ...

  5. java File基本操作,以及递归遍历文件夹

    java 的文件操作,相对来说是比较重要的,无论是编写CS还是BS程序,都避免不了要与文件打交道,例如读写配置文件等.虽然现在很多框架都直接帮你做好了这一步! java.io.File 底层是调用与c ...

  6. 【linux-./configure 配置文件时出错问题】

    环境是:centos 5.6 安装系统时,可能安装的是标准的精简版本,所以没有选择软件依赖包,很多软件都没有安装. 现在需要安装软件,安装软件时报错: make: *** 没有指明目标并且找不到 ma ...

  7. java基础之介绍

    1.JAVA涉及在服务器领域上主要有 Linux.Unix.Windows等(其中Linux和Unix是大部分服务器用的主要的系统) 2.JAVA之所以发展的原因 1.java得到了很多的支持,拥有许 ...

  8. Idea设置签名

    IntelliJ IDEA如何设置头注释,自定义author和date   下面这张图,保证你一看就会: 下面这个模板,你拿去改一改就行了. 1 /** 2 * @Author: Gosin 3 * ...

  9. CF987C Three displays 暴力

    题意翻译 题目大意: nnn个位置,每个位置有两个属性s,cs,cs,c,要求选择3个位置i,j,ki,j,ki,j,k,使得si<sj<sks_i<s_j<s_ksi​< ...

  10. luoguP4921 情侣?给我烧了!

    luogu 考虑对于\(n\)对情侣,恰好\(k\)对是和谐的方案数是 \[ ans[n][k]=\binom{n}{k}A^k_n2^kg(n-k) \] \(g(n)\)为全部\(n\)对情侣不和 ...