一、锁

  Lock(1次放1个)

    什么时候用到锁:

      线程安全,多线程操作时,内部会让所有线程排队处理。如:list、dict、queue

      线程不安全,

import threading
import time
v = []
lock = threading.Lock() #实例化了一个对象******
def func(arg):
lock.acquire() #加锁
v.append(arg)
time.sleep(0.5)
m = v[-1]
print(arg,m)
lock.release() #加锁就要有解锁对应
for i in range(1,11):
t = threading.Thread(target=func,args=(i,))
t.start()

  RLock(1次放1个)

    与Lock用法一致,但是RLock可以锁多次(必须有响应的解锁次数),Lock只能锁一次

import threading
import time
v = []
lock = threading.RLock()
def func(arg):
lock.acquire()  #锁了两次
lock.acquire()
v.append(arg)
time.sleep(0.1)
m = v[-1]
print(arg,m)
lock.release()  #解锁两次
lock.release() for i in range(1,11):
t = threading.Thread(target=func,args=(i,))
t.start()

  BoundedSemaphore(1次方固定个数个)

import time
import threading
lock = threading.BoundedSemaphore(3) #参数是多少就一次放过去多少个线程
def func(arg):
lock.acquire()
print(arg)
time.sleep(1)
lock.release()
for i in range(1,11):
t = threading.Thread(target=func,args=(i,))
t.start()

  Condition(1次放N个)

import time
import threading
lock = threading.Condition()
def func(arg):
print("start")
lock.acquire()
lock.wait() #****
print(arg)
time.sleep(1)
lock.release()
for i in range(1,11):
t = threading.Thread(target=func,args=(i,))
t.start()
while 1:
num = int(input(">>>>>")) #输入多少本次就会放多少个线程
lock.acquire() #****
lock.notify(num)
lock.release() #****
#也可以通过函数逻辑判断的返回值
def xx():
print("来执行函数了")
input(">>>>")
return True
def func(arg):
print("线程来了")
lock.wait_for(xx)
print(arg)
time.sleep(1)
for i in range(1,11):
t = threading.Thread(target=func,args=(i,))
t.start()

  Event(1次放所有)

import threading
lock = threading.Event()
def func(arg):
print("线程来了")
lock.wait()#加锁
print(arg)
for i in range(1,11):
t = threading.Thread(target=func,args=(i,))
t.start()
input(">>>>")
lock.set() #解锁,如果后面不加锁上面的wait就失效了
input(">>>>")
lock.clear() #再次上锁
for i in range(1,11):
t = threading.Thread(target=func,args=(i,))
t.start()
input(">>>>")
lock.set()

  总结:

    线程安全,列表和字典线程安全

    为什么要加锁:

      非线程安全

      控制一段代码

二、threading.local

  作用:

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

    {

      线程id:{......}

      线程id:{......}

      线程id:{......}

    }

import time
import threading
v = threading.local()
def func(arg):
# 内部会为当前线程创建一个空间用于存储:phone=自己的值
v.phone = arg
time.sleep(1)
print(v.phone,arg) # 去当前线程自己空间取值
for i in range(1,11):
t = threading.Thread(target=func,args=(i,))
t.start()
import time
import threading DATA_DICT = {} def func(arg):
ident = threading.get_ident()
DATA_DICT[ident] = arg
time.sleep(1)
print(DATA_DICT[ident],arg) for i in range(10):
t =threading.Thread(target=func,args=(i,))
t.start()

threading.local原理

import time
import threading
INFO = {}
class Local(object):
def __getattr__(self, item):
ident = threading.get_ident()
return INFO[ident][item]
def __setattr__(self, key, value):
ident = threading.get_ident()
if ident in INFO:
INFO[ident][key] = value
else:
INFO[ident] = {key:value}
obj = Local()
def func(arg):
obj.phone = arg #对象.xx="xxx" 调用了__setattr__方法
time.sleep(1)
print(obj.phone,arg) #对象.xx 调用了__getattr__方法
for i in range(1,11):
t = threading.Thread(target=func,args=(i,))
t.start()

threading.local原理升级版

三、线程池

from concurrent.futures import ThreadPoolExecutor
import time
def func(a1,a2):
time.sleep(1)
print(a1,a2)
#创建了一个线程池(最多5个线程)
pool = ThreadPoolExecutor(5)
for i in range(1,21):
#去线程池中申请一个线程
pool.submit(func,i,"a")

四、生产者消费者模型

  三部件:

    生产者

      队列,先进先出

      栈,后进先出

    消费者

  生产者消费者模型解决了什么问题:不用一直等待的问题

import time
import threading
import queue
q = queue.Queue()#线程安全
def producer(id):
while 1:
time.sleep(2)
q.put("包子")
print("厨师%s生产了一个包子"%id)
for i in range(1,3):
t = threading.Thread(target=producer,args=(i,))
t.start()
def consumer(id):
while 1:
time.sleep(1)
q.get("包子")
print("顾客%s吃了一个包子"%id)
for i in range(1,4):
t = threading.Thread(target=consumer,args=(i,))
t.start()

示例

锁、threading.local、线程池的更多相关文章

  1. CIL锁,GIL与线程池的区别,进程池和线程池,同步与异步

    一.GIL锁 什么是GIL? 全局解释器锁,是加在解释器上的互斥锁 GC是python自带的内存管理机制,GC的工作原理:python中的内存管理使用的是应用计数,每个数会被加上一个整型的计数器,表示 ...

  2. 并发编程中死锁、递归锁、进程/线程池、协程TCP服务器并发等知识点

    1.死锁 定义; 类似两个人分别被囚禁在两间房子里,A手上拿着的是B囚禁房间的钥匙,而B拿着A的钥匙,两个人都没法出去,没法给对方开锁,进而造成死锁现象.具体例子代码如下: # -*-coding:u ...

  3. Java多线程(三)锁对象和线程池

    1:锁(Lock) 1.1       java提供了一个锁的接口,这个锁同样可以达到同步代码块的功能,API文档上说使用锁比使用synchronized更加灵活. 1.2       如何使用这个“ ...

  4. GIL锁和进程/线程池

    GIL锁 1.GIL锁 全局解释器锁,就是一个把互斥锁,将并发变成串行,同一时刻只能有一个线程使用共享资源,牺牲效率,保证数据安全,也让程序员避免自己一个个加锁,减轻开发负担 带来的问题 感觉单核处理 ...

  5. python中多进程multiprocessing、多线程threading、线程池threadpool

    浅显点理解:进程就是一个程序,里面的线程就是用来干活的,,,进程大,线程小 一.多线程threading 简单的单线程和多线程运行:一个参数时,后面要加逗号 步骤:for循环,相当于多个线程——t=t ...

  6. [Python]threading local 线程局部变量小測试

    概念 有个概念叫做线程局部变量.一般我们对多线程中的全局变量都会加锁处理,这样的变量是共享变量,每一个线程都能够读写变量,为了保持同步我们会做枷锁处理.可是有些变量初始化以后.我们仅仅想让他们在每一个 ...

  7. C#多线程和线程池 【转】

    1.概念  1.0 线程的和进程的关系以及优缺点 windows系统是一个多线程的操作系统.一个程序至少有一个进程,一个进程至少有一个线程.进程是线程的容器,一个C#客户端程序开始于一个单独的线程,C ...

  8. C#多线程和线程池

    1.概念  1.0 线程的和进程的关系以及优缺点 windows系统是一个多线程的操作系统.一个程序至少有一个进程,一个进程至少有一个线程.进程是线程的容器,一个C#客户端程序开始于一个单独的线程,C ...

  9. C#多线程和线程池[转]

    1.概念  1.0 线程的和进程的关系以及优缺点 windows系统是一个多线程的操作系统.一个程序至少有一个进程,一个进程至少有一个线程.进程是线程的容器,一个C#客户端程序开始于一个单独的线程,C ...

  10. GIL 线程池 进程池 同步 异步

    1.GIL(理论 重点)2.线程池 进程池3.同步 异步 GIL 是一个全局解释器锁,是一个互斥锁 为了防止竞争解释器资源而产生的 为何需要gil:因为一个python.exe进程中只有一份解释器,如 ...

随机推荐

  1. 《构建之法》——GitHub和Visual Studio的基础使用

    git地址 https://github.com/microwangwei git用户名 microwangwei 学号后五位 62214 博客地址 https://www.cnblogs.com/w ...

  2. SpringCloud服务注册与发现中心-Eureka

    1.服务注册与发现的好处: 假设没有这个东西,那么如果存在a,b,c三个同样的服务: 而现在有一个u服务需要用到a或b或c提供的接口,那么u里面肯定是需要配置这三个服务的地址,然后调用的时候还有问题就 ...

  3. LeetCode 897. 递增顺序查找树(Increasing Order Search Tree)

    897. 递增顺序查找树 897. Increasing Order Search Tree 题目描述 给定一个树,按中序遍历重新排列树,使树中最左边的结点现在是树的根,并且每个结点没有左子结点,只有 ...

  4. [转帖]理解k8s 的 Ingress

    理解k8s 的 Ingress https://www.jianshu.com/p/189fab1845c5/ 暴露一个http服务的方式 service 是 k8s 暴露http服务的默认方式, 其 ...

  5. FZU2018级算法第五次作业 missile(排序+枚举)

    在解题报告之前,首先对同一次作业中另外一题(求逆序对)某人在未经冰少允许情况下,擅自登录冰少账号,原模原样剽窃冰少代码,并且最终还被评为优秀作业的行为表示严正抗议! 题目大意: 二维平面上给出 n 个 ...

  6. 机器学习之主成分分析PCA原理笔记

    1.    相关背景 在许多领域的研究与应用中,通常需要对含有多个变量的数据进行观测,收集大量数据后进行分析寻找规律.多变量大数据集无疑会为研究和应用提供丰富的信息,但是也在一定程度上增加了数据采集的 ...

  7. vagrant root 登录虚拟机

    这个问题本来觉得是个特别简单的问题,昨天弄的时候折腾了半晚上.所以打算记录下过程,主要也被网上的各种信息误导了. 1 先看下我这vagrant配置信息 Vagrant.configure(" ...

  8. ASP.NET Core依赖注入多个服务实现类

    依赖注入在 ASP.NET Core 中起中很重要的作用,也是一种高大上的编程思想,它的总体原则就是:俺要啥,你就给俺送啥过来. 服务类型的实例转由容器自动管理,无需我们在代码中显式处理. 因此,有了 ...

  9. 手动编译ts的经过

    动机 以前写ts或者es6,都是用在脚手架搭建的项目中,比如vue和react,当时当我识图写一个ts的demo的,我还要创建一个完整的vue或者react项目?明显不合适,那就要研究一下如何手动搭建 ...

  10. vue 写一个炫酷的轮播图

    效果如上图: 原理: 1.利用css 的 transform 和一些其他的属性,先选五张将图片位置拍列好,剩余的隐藏 2.利用 js 动态切换类名,达到切换效果 css代码如下 .swiper-cer ...