python多线程并发

网络编程GIL

孤人 提交于 2019-11-27 08:02:38
GIL全局解释器锁 """ In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. """ """ ps:python解释器有很多种 最常见的就是Cpython解释器 GIL本质也是一把互斥锁:将并发变成串行牺牲效率保证数据的安全 用来阻止同一个进程下的多个线程的同时执行(同一个进程内多个线程无法实现并行但是可以实现并发) python的多线程没法利用多核优势 是不是就是没有用了? GIL的存在是因为CPython解释器的内存管理不是线程安全的 垃圾回收机制 1.引用计数 2.标记清除 3.分代回收 研究python的多线程是否有用需要分情况讨论 四个任务 计算密集型的 10s 单核情况下 开线程更省资源 多核情况下 开进程 10s 开线程 40s 四个任务 IO密集型的 单核情况下 开线程更节省资源 多核情况下 开线程更节省资源 """ # 计算密集型# from

Python GIL锁 死锁 递归锁 event事件 信号量

 ̄綄美尐妖づ 提交于 2019-11-27 07:58:06
一 GIL (全局解释器锁) 1.什么是GIL:指的是全局解释器锁,本质也是一把互斥锁。主要是保证同一进程下的多个线程将不可能在同一时间使用解释器,从而保证了解释器的数据安全 (同一个进程内多个线程无法实现并行但是可以实现并发) 。 2.注意: 1):GIL仅存在cpython解释器中,其他解释器不存在,并不是python语言的缺点。 2):GIL保护的是解释器级别数据的安全(比如对象的引用计数,垃圾分代数据等等),对于程序中自定义的数据没有任何保护效果所以自定义共享数据要自己加锁。 3.GIL加锁与解锁的时机 加锁:在调用解释器时立即加锁 解锁时机:当线程遇到IO操作和超过设定的时间值时解锁。 总结: 1.单核下无论是IO密集还是计算密集GIL都不会产生任何影响 2.多核下对于IO密集任务,GIL会有细微的影响,基本可以忽略 3.Cpython中IO密集任务应该采用多线程,计算密集型应该采用多进程 GIL的优点: 保证了CPython中的内存管理是线程安全的 GIL的缺点: 互斥锁的特性使得多线程无法并行 二 死锁(相互等待,互不释放) 1.什么是死锁: 当程序出现了不止一把锁,分别被不同的线程持有, 有一个资源 要想使用必须同时具备两把锁 这时候程序就会进程无限卡死状态 ,这就称之为死锁 2. mutexA = Lock() mutexB = Lock() class

python线程基础

我的未来我决定 提交于 2019-11-27 07:05:55
一 基本概念 1 并行和并发 1 并行,parallel 同时做某些事,可以互不干扰的同一时刻做几件事 如高速公路上的车道,同一时刻,可以有多个互不干扰的车运行 在同一时刻,每条车道上可能同时有车辆在跑,是同时发生的概念 2 并发,concurrency 也是同时做某事,但强调的是同一时段做了几件事。 并行是可以解决并发问题的。 2 并发的解决 1 队列,缓冲区 队列:排队就是队列,先进先出,解决了资源使用的问题。 缓冲区:排程的队列,其实就是一个缓冲地带,就是缓冲区 优先队列:对比较重要的事进行及时的处理,此处就是优先队列 2 争抢 只开一个窗口,有可能没秩序,也就是谁挤进去就给谁打饭 挤到窗口的人占据窗口,直到达到饭菜离开,其他人继续争抢,会有一个人占据窗口,可以视为锁定窗口,窗口就不能为其他人提供服务了,这是一种锁机制,抢到资源就上锁,排他性锁,其他人只能等候 争抢也是一种高并发解决方案,但是,不好,因为有人可能长时间抢不到。 3 预处理 一种提前加载用户需要的数据的思路,如预热,预加载等,缓存中常用 缓存的思想就是将数据直接拿到,进行处理。 4 并行 可通过购买更多的服务器,或开多线程,进行实现并行处理,来解决并发问题,这些都是水平扩展, 5 提速 提高单个CPU性能,或者单个服务器安装更多的CPU,但此和多个服务器相比成本较高 6 消息中间件

python并发编程-进程间通信-Queue队列使用-生产者消费者模型-线程理论-创建及对象属性方法-线程互斥锁-守护线程-02

Deadly 提交于 2019-11-27 03:03:33
目录 进程补充 进程通信前言 Queue队列的基本使用 通过Queue队列实现进程间通信(IPC机制) 生产者消费者模型 以做包子买包子为例实现当包子卖完了停止消费行为 线程 什么是线程 为什么要有线程 开进程 开线程 开启线程的两种方式 方式一 方式二 线程之间数据共享 线程对象的其他属性和方法 线程运用互斥锁 守护线程 主线程运行结束之后为什么需要等待子线程结束才能结束呢? 测试 线程互斥锁 不加锁遇到延迟的情况 加锁后遇到延迟 进程补充 进程通信前言 要想 实现进程间通信 ,可以用 管道 或者 队列 队列比管道更好用(队列自带管道和锁) 队列特点:先进先出 堆栈特点:先进后出 我们采用队列来实现进程间数据通信,下面先介绍一下队列 Queue队列的基本使用 基本方法: q.put(元素) q.get() q.get_nowait() q.full() q.empty() from multiprocessing import Process, Queue q = Queue(5) # 实例化出一个对象 # -------------------------------------- # q.put(元素) 往队列里放东西 # 如果队列满了还往里面放,就会等在这里 # -------------------------------------- # q.put(1) # q

【Python与线程】

﹥>﹥吖頭↗ 提交于 2019-11-27 02:57:38
原文: http://106.13.73.98/__/6/ 目录 一、全局解释器锁GIL 二、Python线程模块的选择 三、线程的创建 三、锁机制 四、信号量 五、事件 六、条件 七、定时器 八、线程队列 九、线程池 补充:线程安全 import threading obj = threading.local()# local():可实现,多线程操作某一数据,不会出现数据混乱的情况# 原理:空间换时间 def add(i): obj.n = i print(i, obj.n, threading.current_thread().ident) for i in range(20): th = threading.Thread(target=add, args=(i,)) th.start() 一、全局解释器锁GIL Python代码的执行由Python虚拟机(也叫解释器主循环)来控制。Python在设计之初就考虑到要在主循环中同时只有一个线程在执行。虽然Python解释器中可以“运行”多个线程,但在任意时刻只有一个线程在解释器中运行. 对于Python虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁保证了同一时刻只有一个线程在运行. 同一时间点,GIL只允许同一个进程中的一个线程访问cpu,即CPython解释器中没有真正的线程并行,只有进程可以实现。故I/O操作多时

【Python与线程】

谁说胖子不能爱 提交于 2019-11-27 02:50:18
原文: http://106.13.73.98/__/6/ 目录 一、全局解释器锁GIL 二、Python线程模块的选择 三、线程的创建 三、锁机制 四、信号量 五、事件 六、条件 七、定时器 八、线程队列 九、线程池 补充:线程安全 import threading obj = threading.local()# local():可实现,多线程操作某一数据,不会出现数据混乱的情况# 原理:空间换时间 def add(i): obj.n = i print(i, obj.n, threading.current_thread().ident) for i in range(20): th = threading.Thread(target=add, args=(i,)) th.start() 一、全局解释器锁GIL Python代码的执行由Python虚拟机(也叫解释器主循环)来控制。Python在设计之初就考虑到要在主循环中同时只有一个线程在执行。虽然Python解释器中可以“运行”多个线程,但在任意时刻只有一个线程在解释器中运行. 对于Python虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁保证了同一时刻只有一个线程在运行. 同一时间点,GIL只允许同一个进程中的一个线程访问cpu,即CPython解释器中没有真正的线程并行,只有进程可以实现。故I/O操作多时

python之并发编程

拜拜、爱过 提交于 2019-11-27 02:21:12
一、操作系统与应用程序   在没有介绍线程与进程相关的知识之前,需要给大家引入一个知识点,关于操作系统与应用程序又与线程与进程有什么关系?   硬件 ...  装系统   系统就是一个有程序员写出来的软件,该软件用于控制计算机硬件,让他们之间相互配合  装软件(安装应用程序)   ...  并发与并行   并发,假,由于执行速度贴别快,感觉不到停顿   并行,真,创建10个人同时操作  线程与进程   单线程与单进程   一个软件默认一个进程,可以有多个   线程:   工作的最小单元   共享进程中的所有资源   每个线程可以分担一些任务,最终完成最后的结果   进程:   独立开辟内存   进程之间的数据隔离   注:GIL锁,是在进程中起到了阻塞线程的作用  总结:   1.操作系统帮助开发者操作硬件   2.程序员写好代码在操作系统上运行(依赖解释器)   3.任务特别多    python多线程情况下:   计算密集型操作:效率低   IO操作:效率高   python多进程情况下:   计算密集型操作:效率高(浪费资源)   IO操作:效率高(浪费资源)   以后写python时:   IO密集型用多线程   计算密集型用多进程   java多线程情况下:   计算密集型操作:效率高   IO操作:效率高   java多进程情况下:   计算密集型操作:效率高(浪费资源

python之并发编程

五迷三道 提交于 2019-11-27 02:20:52
一、什么是进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。 狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed)。 广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。 进程理论 程序:一堆死代码 进程:正在运行的程序 进程是资源单位,进程与进程之间数据是绝对意义上的物理隔离,但是可以利用某些技术实现数据交互(消息队列) 动态性:进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。 并发性:任何进程都可以同其他进程一起并发执行 独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位; 异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进 结构特征:进程由程序、数据和进程控制块三部分组成。 多个不同的进程可以包含相同的程序:一个程序在不同的数据集里就构成不同的进程,能得到不同的结果;但是执行过程中,程序不能发生改变   注意:同一个程序执行两次,就会在操作系统中出现两个进程

Python爬虫常见问题

别说谁变了你拦得住时间么 提交于 2019-11-26 17:52:15
第一个问题:JS加密如何突破 (1) 熟练掌握Chrome的开发者工具的各个功能,Elements, Network,Source (2) 认真观察,善于思考。Network查看加载流程,找可疑的xhr请求,设置xhr断点,通过Call Stack 回溯js执行过程,边回溯边查看上下文代码。能读懂js,知道js的相关知识,比如js里面的window变量。 (3) 以上是通过debug js找到js加密解密的代码,然后通过Python重新实现,这个过程很长,可能耗费你几天的时间,一旦网站改变一下js算法你的Python实现就不能用了。 (4) 用Selenium可简单突破,并且网站随便该都无所谓。唯一遗憾的是,Selenium的运行效率较差。但是,作为一个能用js加密来保护数据的网站,单价的运行效率应该足以满足网站的访问频率限制。这时候,更多的思考是如何增加资源(IP、账号)来提高抓取效率。 第二个问题、多线程、协程,多进程的选择 (1)爬虫是IO密集型任务,大部分时间花在网络访问上,所以多进程不适合网络爬虫,而多线程、异步IO协程更适合,而异步IO是最适合的,它相比多线程,协程间的切换代价更小,我们提倡使用异步IO而非多线程。异步IO的模块主要是:aysncio, aiohttp, aiomysql 等。 (2)网页爬下来后从中提取想要的数据是CPU密集型的

Python自学第九周(2)

让人想犯罪 __ 提交于 2019-11-26 17:39:44
子线程编程守护线程 当主线程结束,不管子线程结束没有,全部结束 1 #Author: Zachary 2 import threading,time 3 def run(n): 4 print("task",n) 5 time.sleep(2) 6 print("task done",n,threading.current_thread()) 7 start_time = time.time() 8 t_objs = [] 9 for i in range(50): 10 t= threading.Thread(target=run,args=("t-%s"%i ,)) 11 t.setDaemon(True) #把当前线程设置为守护线程 12 t.start() 13 t_objs.append(t) 14 15 print("-----------------all threads has finished") 16 print("cost:",time.time() - start_time) 17 ##将main线程设置为Daemon线程,它做为程序主线程的守护线程,当主线程退出时,m线程也会退出,由m启动的其它子线程会同时退出,不管是否执行完任务 GIL锁(线程锁)也称之为互斥锁 如果是在windows上运行 1 #Author: Zachary 2 import