一 死锁现象 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程,如下就是死锁 from threading import Thread from threading import Lock import time # 实例化两把不同的锁 mutexA = Lock() mutexB = Lock() class MyThread(Threa…
Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密集型效率验证.进程池/线程池 目录 Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密集型效率验证.进程池/线程池 1. 死锁现象 2. 递归锁 3. 信号量 4. GIL全局解释器锁 1. 背景 2. 加锁的原因: 3. GIL与Lock锁的区别 4. 为什么GIL保证不了自己数据的安全? 5. 验证计算密集型.IO密集型的效率 6. 多线程实现socket通信 7. 进程池,线程…
一堆锁 死锁现象 (重点) 死锁指的是某个资源被占用后,一直得不到释放,导致其他需要这个资源的线程进入阻塞状态. 产生死锁的情况 对同一把互斥锁加了多次 一个共享资源,要访问必须同时具备多把锁,但是这些锁被不同线程或者进程所持有,就会导致相互等待对方释放从而程序就卡死了 第二种情况的解决方法: 抢锁一定按照相同的顺序去抢 给抢锁加上超时,如果超时则放弃执行 递归锁 (了解) 与普通的区别 相同: 多线程之间都有互斥的效果 不同: 同一个线程可以对这个锁执行多次acquire 解决方法 同一个线程…
线程理论 python 并发编程 多线程 开启线程的两种方式 python 并发编程 多线程与多进程的区别 python 并发编程 多线程 Thread对象的其他属性或方法 python 并发编程 多线程 守护线程 python 并发编程 多线程 互斥锁 python GIL解释器锁与互斥锁 python 并发编程 多线程 死锁现象与递归锁 python 并发编程 多线程 信号量 python 并发编程 多线程 event python 并发编程 多线程 定时器 python 并发编程 多线程…
9.94 守护线程与守护进程的区别 1.对主进程来说,运行完毕指的是主进程代码运行完毕2.对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕​详细解释:1.主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束,2.主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收).因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程…
一 守护线程 from threading import Thread import time def foo(): print(123) time.sleep(1) print('end123') def bar(): print(456) time.sleep(3) print('end456') t1 = Thread(target=foo) t2 = Thread(target=bar) t1.daemon = True t1.start() t2.start() print('主线程'…
一.GIL全局解释器锁 1.什么是全局解释器锁 GIL本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL,同一进程内的多个线程,必须抢到GIL之后才能使用Cpython解释器来执行自己的代码,即同一进程下的多个线程无法实现并行,但是可以实现并发. #1 所有数据都是共享的,这其中,代码作为一种数据也是被所有线程共享的(test.py的所有代码以及Cpython解释器的所有代码) #2 所有线程的任务,都需要将任务的代码当做参数传给解释器的代码去执行,即所有的线程要想运行自己的任务,…
GIL.死锁现象与递归锁.信号量.Event事件.线程queue 一.GIL全局解释器锁 1.什么是全局解释器锁 GIL本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL,同一进程内的多个线程,必须抢到GIL之后才能使用Cpython解释器来执行自己的代码,即同一进程下的多个线程无法实现并行,但是可以实现并发. #1 所有数据都是共享的,这其中,代码作为一种数据也是被所有线程共享的(test.py的所有代码以及Cpython解释器的所有代码) #2 所有线程的任务,都需要将任务的代…
前导理论知识见:python并发编程&多线程(一) 一 threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性 官网链接:https://docs.python.org/3/library/threading.html?highlight=threading#(装B模式加载中…………)   二 开启线程的两种方式 #方式一 from threading import Thread import time def sayhi…
本篇理论居多,实际操作见:  python并发编程&多线程(二) 一 什么是线程 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程 车间负责把资源整合到一起,是一个资源单位,而一个车间内至少有一个流水线 流水线的工作需要电源,电源就相当于cpu 所以,进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位. 多线程(即多个控制线程)的概念…
一:死锁现象和递归锁 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程,如下就是死锁 from threading import Thread,Lock,RLock import time # mutexA=Lock() # mutexB=Lock() mutexB=mutexA=RLock() class Mythead(Thread):…
一.同步锁 三个需要注意的点: #1.线程抢的是GIL锁,GIL锁相当于执行权限,拿到执行权限后才能拿到互斥锁Lock,其他线程也可以抢到GIL,但如果发现Lock仍然没有被释放则阻塞,即便是拿到执行权限GIL也要立刻交出来 #2.join是等待所有,即整体串行,而锁只是锁住修改共享数据的部分,即部分串行,要想保证数据安全的根本原理在于让并发变成串行,join与互斥锁都可以实现,毫无疑问,互斥锁的部分串行效率要更高 #3. 一定要看本小节最后的GIL与互斥锁的经典分析 GIL VS Lock  …
Pythpn并发编程--多线程与协程 目录 Pythpn并发编程--多线程与协程 1. 进程与线程 1.1 概念上 1.2 多进程与多线程--同时执行多个任务 2. 并发和并行 3. Python多线程--futures 3.1 多线程用法 3.2. 为什么多线程每次只允许只能有一个线程执行? 3.3 多线程的缺点 4. python协程--asyncio 4.1 概念 4.2 Asyncio原理 4.3 如何使用? 4.4. 协程的优点 6. 选择多线程还是协程 1. 进程与线程 1.1 概念…
编程的乐趣在于让程序越来越快,这里将给大家介绍一个种加快程序运行的的编程方式--多线程   1 著名的全局解释锁(GIL) 说起python并发编程,就不得不说著名的全局解释锁(GIL)了.有兴趣的同学可以我查找一下相关的资料了解一下GIL,在这里大家只要知道一点,因为GIL的存在, 对于任何Python程序,不管有多少的处理器,任何时候都总是只有一个线程在执行. 下面先看一个例子: #!/usr/bin/env python # -*- coding: utf-8 -*- ""&qu…
目录 结合多线程实现服务端并发(不用socketserver模块) 服务端代码 客户端代码 CIL全局解释器锁****** 可能被问到的两个判断 与普通互斥锁的区别 验证python的多线程是否有用需要分情况讨论 计算密集型任务 IO密集型任务 小结论 死锁与递归锁 死锁 递归锁 RLock 信号量 Semaphore Event事件 线程结合队列 结合多线程实现服务端并发(不用socketserver模块) socketserver自带多线程 服务端代码 import socket from…
互斥锁 并行变成串行,牺牲效率 保证数据安全,实现局部串行 保护不同的数据,应该加不同的锁 现在一个进程 可以有多个线程 所有线程都共享进程的地址空间 实现数据共享 共享带来问题就会出现竞争 竞争就会出现改乱数据 每个子线程都去执行task函数 代码 都拿到n=99 这种方法效率高 ,但是导致数据不安全 并发执行 from threading import Thread import time n = 100 def task(): # 定义全局变量 global n tmp = n time.…
大家好,并发编程 进入第三篇. 今天我们来讲讲,线程里的锁机制. 本文目录 何为Lock( 锁 )?如何使用Lock( 锁 )?为何要使用锁?可重入锁(RLock)防止死锁的加锁机制饱受争议的GIL(全局锁) 何为Lock( 锁 )?如何使用Lock( 锁 )?为何要使用锁?可重入锁(RLock)防止死锁的加锁机制饱受争议的GIL(全局锁) . 何为Lock( 锁 )? 何为 Lock( 锁 ),在网上找了很久,也没有找到合适的定义.可能 锁 这个词已经足够直白了,不需要再解释了. 但是,对于新…
一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终端 #并发运行,效率高,但竞争同一打印终端,带来了打印错乱 from multiprocessing import Process import os,time def work(): print('%s is running' %os.getpid()) time.sleep(2) print('…
GIL与多线程 有了GIL的存在,同一时刻同一进程中只有一个线程被执行 多进程可以利用多核,但是开销大,而python的多线程开销小,但却无法利用多核优势 1.cpu到底是用来做计算的,还是用来做I/O的? 2.多个cpu,意味着可以有多个核并行完成计算,所以多核提升的是计算性能,cpu越多计算性能越高 3.无论是多核还是单核CPU ,每个cpu一旦遇到I/O阻塞,仍然需要等待,所以多核对I/O操作没什么用处 CPU用来计算 结论: 1.对计算来说,cpu越多越好,但是对于I/O来说,再多的cp…
首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念. 就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码. >有名的编译器例如GCC,INTEL C++,Visual C++等.Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行. 像其中的JPython就没有GIL.然而因为CPython是大部分环境下默认的Python执行环境.所以在很多人的概…
GIL与Lock Python已经有一个GIL来保证同一时间只能有一个线程来执行了,为什么这里还需要互斥锁lock? 锁的目的是为了保护共享的数据,同一时间只能有一个线程来修改共享的数据 GIT保证了一个进程内有多个线程,只有一个线程执行,保证python垃圾回收线程安全 结论:保护不同的数据就应该加不同的锁,针对不同的数据就应该加不同锁. GIL 与Lock是两把锁,保护的数据不一样,前者是解释器级别的(当然保护的就是解释器级别的数据,比如垃圾回收的数据(垃圾回收线程)),后者是保护用户自己开…
线程queue 线程之间已经是共享数据的,为什么还使用线程queue? 线程需要自己加锁,线程queue帮我们处理好加锁的问题 有三种不同的用法 第一种方法: class queue.Queue(maxsize=0) #队列:先进先出 put('four',block=,timeout=) 第一个参数: 放入的数据 第二个参数: block=True 时 队列满了,再放数据不抛出异常,程序卡主,不指定block参数,默认是True block=false时,队列满了,再放数据,不阻塞,抛出异常…
做完工作这个进程就应该被销毁 单线程情况: 一个进程 ,默认有一个主线程 ,这个主线程执行完代码后 ,就应该自动销毁.然后进程也销毁. 多线程情况: 主线程代表进程结束 一个进程可以开多个线程,默认开启进程 ,首先开一个主线程 ,然后开子线程 ,主线程代码执行完毕后 ,也要等所有子线程 ,执行完毕后 ,再销毁 ,然后到进程销毁. 守护进程 要等主进程挂了后 守护进程才挂 1.对主进程来说,运行完毕指的是主进程代码运行完毕 2.对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完…
操作系统比作一家公司,进程相当于一个部门  线程相当于一个部门的成员 进程之间是互相隔离的 一 什么是线程 1. 每启动一个进程 至少有一个线程,  在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 2. 一个进程里的线程里面的成员 与其他进程的线程的成员 互相隔离数据不共享的 3.同一个进程里多个线程是共享资源的 进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位. 多线程(即多个控制线程)的概念是,在一个进程中存在多个线程,多…
进程内会生成一个主线程,让主线程执行server函数,server函数核心是accept(),让主线程干accept的工作, 建立连接,每建立一个连接应该执行通信函数 每建立一个连接就是生成一个子线程 服务端 from socket import * from threading import Thread def communicate(conn): ''' 通信功能 ''' while True: try: data = conn.recv(1024) if not data:break c…
event实现了一个线程通知另外一个线程 线程的一个关键特性是每个线程都是独立运行且状态不可预测. 1.为什么要使用Event对象: 如果程序中的其 他线程需要通过判断某个线程的状态来确定自己下一步的操作,这时线程同步问题就会变得非常棘手.为了解决这些问题,我们需要使用threading库中的Event对象. 2.Event对象实现原理 对象包含一个可由线程设置的信号标志,它允许线程等待某些事件的发生.在 初始情况下,Event对象中的信号标志被设置为Fasle.如果有线程等待一个Event对象…
定时器 就是隔多长时间去触发任务执行 指定n秒后执行某操作 Timer如何使用,看Timer源码 class Timer(Thread): """Call a function after a specified number of seconds: t = Timer(30.0, f, args=None, kwargs=None) t.start() t.cancel() # stop the timer's action if it's still waiting &q…
一 信号量 信号量也是一把锁,可以指定信号量为5,对比互斥锁同一时间只能有一个任务抢到锁去执行,信号量同一时间可以有5个任务拿到锁去执行 如果说互斥锁是合租房屋的人去抢一个厕所,那么信号量就相当于一群路人争抢公共厕所,公共厕所有多个坑位,这意味着同一时间可以有多个人上公共厕所,但公共厕所容纳的人数是一定的,这便是信号量的大小 from threading import Thread from threading import Semaphore from threading import cur…
介绍 Thread实例对象的方法 # isAlive(): 返回线程是否活动的. # getName(): 返回线程名. # setName(): 设置线程名. threading模块提供的一些方法: # threading.currentThread(): 返回当前的线程变量. # threading.enumerate(): 返回一个包含正在运行的线程的list.正在运行指线程启动后.结束前,不包括启动前和终止后的线程. # threading.activeCount(): 返回正在运行的线…
1.开进程的开销远大于开线程 2 同一进程内的线程共享该进程的数据,进程之间地址空间是隔离的 1 开进程的开销远大于开线程 from multiprocessing import Process def work(): print('hello') if __name__ == '__main__': #在主进程下开启子进程 p = Process(target=work) p.start() print('主进程') ''' 主进程 hello ''' 执行结果如下,p.start ()将开启…