python-day36--并发编程之多线程
十三、死锁、递归锁
1.所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程,如下就是死锁
from threading import Lock,Thread
import time
mutexB=Lock()
mutexA=Lock()
class MyThread(Thread):
def run(self):
self.f1()
self.f2() def f1(self):
mutexA.acquire()
print('%s拿到了A锁' %self.name)
mutexB.acquire()
print('%s拿到了B锁' %self.name)
mutexB.release()
mutexA.release() def f2(self):
mutexB.acquire()
print('%s拿到了B锁' %self.name)
time.sleep(1)
mutexA.acquire()
print('%s拿到了A锁' %self.name)
mutexA.release()
mutexB.release() if __name__ == '__main__':
for i in range(10):
t=MyThread()
t.start() # 结果
# Thread-1拿到了A锁
# Thread-1拿到了B锁
# Thread-1拿到了B锁
# Thread-2拿到了A锁
。。。。 卡住了
2.解决方法,递归锁,在Python中为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock。
这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。上面的例子如果使用RLock代替Lock,则不会发生死锁:
from threading import Thread,RLock
import time
mutexB=mutexA=RLock()
class MyThread(Thread):
def run(self):
self.f1()
self.f2() def f1(self):
mutexA.acquire()
print('\033[32m%s 拿到A锁' %self.name)
mutexB.acquire()
print('\033[45m%s 拿到B锁' %self.name)
mutexB.release()
mutexA.release() def f2(self):
mutexB.acquire()
print('\033[32m%s 拿到B锁' %self.name)
time.sleep(1)
mutexA.acquire()
print('\033[45m%s 拿到A锁' %self.name)
mutexA.release()
mutexB.release() if __name__ == '__main__':
for i in range(2):
t=MyThread()
t.start() # 结果:
# Thread-1 拿到A锁
# Thread-1 拿到B锁
# Thread-1 拿到B锁
# Thread-1 拿到A锁
# Thread-2 拿到A锁
# Thread-2 拿到B锁
# Thread-2 拿到B锁
# Thread-2 拿到A锁
十四、信号量Semaphore
Semaphore管理一个内置的计数器,
每当调用acquire()时内置计数器-1;
调用release() 时内置计数器+1;
计数器不能小于0;当计数器为0时,acquire()将阻塞线程直到其他线程调用release()。
from threading import Thread,Semaphore,currentThread
import time,random
sm=Semaphore(5) #限制最大连接数为5
def task():
sm.acquire()
print('%s 上厕所' %currentThread().getName())
time.sleep(random.randint(1,3))
print('%s 走了' %currentThread().getName())
sm.release()
if __name__ == '__main__':
for i in range(20):
t=Thread(target=task)
t.start()
与进程池是完全不同的概念,进程池Pool(4),最大只能产生4个进程,而且从头到尾都只是这 四个进程,不会产生新的,而信号量是产生一堆线程/进程
十五、Event事件
event.isSet():返回event的状态值; event.wait():如果 event.isSet()==False将阻塞线程; event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度; event.clear():恢复event的状态值为False。
from threading import Thread,Event,currentThread
import time
e=Event() def traffic_lights():
time.sleep(5)
e.set() def car():
print('\033[45m%s 等' %currentThread().getName())
e.wait()
print('\033[45m%s 跑' %currentThread().getName()) if __name__ == '__main__':
for i in range(10):
t=Thread(target=car)
t.start()
traffic_thread=Thread(target=traffic_lights)
traffic_thread.start()
例子
from threading import Thread,Event,currentThread
import time
e=Event()
def conn_mysql():
count=1
while not e.is_set():
if count > 3:
raise ConnectionError('尝试链接的次数过多')
print('\033[45m%s 第%s次尝试' %(currentThread().getName(),count))
e.wait(timeout=1)
count+=1
print('\033[45m%s 开始链接' %currentThread().getName()) def check_mysql():
print('\033[45m%s 检测mysql...' %currentThread().getName())
time.sleep(4) #超时了
e.set()
if __name__ == '__main__':
t=Thread(target=check_mysql)
t.start()
for i in range(3):
t=Thread(target=conn_mysql)
t.start()
重要的例子
十六、定时器
from threading import Timer def hello(n):
print("hello, world",n) t = Timer(3, hello,args=(123,)) #3秒后运行hello函数, 可以传参数
t.start()
十七、线程queue
queue队列 :使用import queue,用法与进程Queue一样
queue.Queue #先进先出 #队列
import queue q=queue.Queue()
q.put('first')
q.put('second')
q.put('third') print(q.get())
print(q.get())
print(q.get())
'''
结果(先进先出):
first
second
third
'''
queue.LifoQueue #last in fisrt out #堆栈
import queue q=queue.LifoQueue()
q.put('first')
q.put('second')
q.put('third') print(q.get())
print(q.get())
print(q.get())
'''
结果(后进先出):
third
second
first
'''
queue.PriorityQueue #存储数据时可设置优先级的队列
import queue q=queue.PriorityQueue()
#put进入一个元组,元组的第一个元素是优先级(通常是数字,也可以是非数字之间的比较),数字越小优先级越高
q.put((20,'a'))
q.put((10,'b'))
q.put((30,'c')) print(q.get())
print(q.get())
print(q.get())
'''
结果(数字越小优先级越高,优先级高的优先出队):
(10, 'b')
(20, 'a')
(30, 'c')
'''
python-day36--并发编程之多线程的更多相关文章
- python week08 并发编程之多线程--理论部分
一. 什么是线程 1.定义 线程就像一条工厂车间里的流水线,一个车间里可以用很多流水线,来执行生产每个零部件的任务. 所以车间可以看作是进程,流水线可以看作是线程.(进程是资源单位,线程是执行单位) ...
- python week08 并发编程之多线程--实践部分
一. threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍 官网链接:https://docs.pytho ...
- Python并发编程04 /多线程、生产消费者模型、线程进程对比、线程的方法、线程join、守护线程、线程互斥锁
Python并发编程04 /多线程.生产消费者模型.线程进程对比.线程的方法.线程join.守护线程.线程互斥锁 目录 Python并发编程04 /多线程.生产消费者模型.线程进程对比.线程的方法.线 ...
- python之并发编程
一 背景知识 顾名思义,进程即正在执行的一个过程.进程是对正在运行程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一.操作系统的其他所 ...
- Python 3 并发编程多进程之队列(推荐使用)
Python 3 并发编程多进程之队列(推荐使用) 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 可以往 ...
- Python 3 并发编程多进程之进程同步(锁)
Python 3 并发编程多进程之进程同步(锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,竞争带来的结果就是错乱,如何控制,就是加锁处理. 1. ...
- Python 3 并发编程多进程之守护进程
Python 3 并发编程多进程之守护进程 主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemo ...
- 使用Python进行并发编程
让计算机程序并发的运行是一个经常被讨论的话题,今天我想讨论一下Python下的各种并发方式. 并发方式 线程(Thread) 多线程几乎是每一个程序猿在使用每一种语言时都会首先想到用于解决并发的工具( ...
- python中并发编程基础1
并发编程基础概念 1.进程. 什么是进程? 正在运行的程序就是进程.程序只是代码. 什么是多道? 多道技术: 1.空间上的复用(内存).将内存分为几个部分,每个部分放入一个程序,这样同一时间在内存中就 ...
- python之并发编程初级篇8
一.进程理论 1)进程介绍 .什么是进程 一个正在进行的过程,或者说是一个程序的运行过程 其实进程是对正在运行的程序的一种抽象/概括的说法 进程的概念起源操作系统,进程是操作最核心的概念之一 操作系统 ...
随机推荐
- js 技巧(智能社教程温故)
1.js 中 NaN === NaN 值为false; 2.parseInt("abc") === NaN;(不是数字) 3.tab 纯js 实现.可以给当前循环的元素添加.i ...
- ELK学习笔记之ELK分析nginx日志
0x00 配置FIlebeat搜集syslog #安装 rpm -ivh filebeat-6.2.3-x86_64.rpm mv /etc/filebeat/filebeat.yml /etc/fi ...
- ELK学习笔记之ELK架构与介绍
0x00 为什么用到ELK 一般我们需要进行日志分析场景:直接在日志文件中 grep.awk 就可以获得自己想要的信息.但在规模较大的场景中,此方法效率低下,面临问题包括日志量太大如何归档.文本搜索太 ...
- lambda表达式Bug——修改捕获变量失败
解<C++ Primer 5th>的 9-50 练习题时,遇到了 lambda表达式值捕获和引用捕获之区别问题. 欲修改捕获的变量 sum,累加之.但当时忘记值捕获和引用捕获是有区别的.下 ...
- 20145307陈俊达《网络对抗》Exp 8 Web基础
20145307陈俊达<网络对抗>Exp 8 Web基础 基础问题回答 1.什么是表单? 表单是一个包含表单元素的区域,表单元素是允许用户在表单中输入信息的元素,表单在网页中主要负责数据采 ...
- 高斯消元&&luogu3389
高斯消元(Gauss) 高斯消元和我们做二元一次方程组差不多 流程: 1.把系数和右边的值就是用二维数组存下来->转化成矩阵 我们的目标是把这个矩阵装换成 上三角的形式 对角线系数全部为1,1下 ...
- ZooKeeper与Kafka相关
Kafka集群搭建: https://www.cnblogs.com/likehua/p/3999538.html https://www.cnblogs.com/mikeguan/p/7079013 ...
- Unity 之 Time
Time.deltaTime 指完成每一帧的时间,根据得到实际的测试,可以看到每一帧的所用时间不一致,差距很微小. Time.deltaTime在Update和FixedUpdate中显示的是不一样 ...
- [luoguP1119]灾后重建
题目链接 毒瘤题 卡spfa 可能dij也卡,没试过 然后放floyd过了 但其实spfa很好打,虽然只有60 让我们来分析一下spfa的效率,假设这个出题人极其毒瘤,出网格图 又因为是在线询问,所以 ...
- Ubuntu下Eclipse安装与编译ns-3遇见的各种问题
感觉Eclipse比其它东西装起来麻烦多了. 问题拾遗 (1)安装 这一块倒是没有什么大的问题,Linux操作系统也不需要像在Windows操作系统下下一些必须的东西(比如CDT等等).安装好了JDK ...