python多线程

深入理解:线程,进程,协程和并行,并发-协程

岁酱吖の 提交于 2020-01-10 02:27:20
爬虫的并发控制: 多进程、多线程、协程 yield 从硬件: 双核四线程(超线程技术): 有两个CPU核心,每个核心有两个逻辑处理器,相当于有四个CPU核心 四核四线程: 有一个CPU核心,每个核心有一个逻辑处理器,相当于有四个CPU核心 从操作系统: 进程和线程,都是CPU任务的执行单位。 进程:早期的操作系统是面向进程的: 表示一个程序的执行活动(打开、执行、保存、关闭) 线程:现在的操作系统都是面向线程: 表示一个进程处理任务时最小调度单位(执行功能a、执行功能b) 一个程序至少开启一个进程,一个进程至少有一个线程。 每个进程都有独立的内存空间,不同进程之间不共享任何状态。 进程之间的通信需要经过操作系统调度控制,通讯效率低、切换开销大。 同一个进程里的多个线程,是共享内存空间,切换开销小,通讯效率高。 线程的工作机制是"抢占式",出现竞争的状态,竞争意味着数据不安全。 引入了"互斥锁":让多个线程安全有序的访问内存空间的机制。 Python的多线程: 类似于 GIL(全局解释器锁):保证一个时间片里只有一个线程在运行。 好处:直接杜绝了多个线程的竞争问题: 坏处:Python的多线程不是真正的多线程。 Python解释器在处理IO阻塞类型的方法时,会释放GIL 如果没有IO操作,该线程会每隔 sys.getcheckinterval() 次释放GIL,让其他线程尝试执行。

python----线程进程协程

余生颓废 提交于 2020-01-09 08:35:00
python线程: import threading import time def show(arg): time.sleep(1) print('thread' + str(arg)) for i in range(10): t = threading.Thread(target=show, args=(i,)) t.start() print('main thread stop') import threading class MyThread(threading.Thread): def __init__(self): threading.Thread.__init__(self) def run(self): print("线程开始运行") t1 = MyThread() t1.start() 通过类创建线程 更多方法: start 线程准备就绪,等待CPU调度 setName 为线程设置名称 getName 获取线程名称 setDaemon 设置为后台线程或前台线程(默认) t.setDaemon(True) 必须在 t.start() 之前调用 如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止 如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止 join

线程、进程和协程

∥☆過路亽.° 提交于 2020-01-09 04:09:29
Treading用于提供线程相关的操作,线程是应用程序中工作的最小单元 #!/usr/bin/env python # coding:utf-8 import threading import time def show(arg): time.sleep(1) print 'thread'+str(arg) for i in range(10): t = threading.Thread(target=show,args=(i,)) t.start() print 'main thread stop' ''' 打印结果: main thread stop thread0 thread5thread4thread1thread2 thread3 thread7thread6thread8 thread9 ''' 上述代码创建了10个进程,然后控制器就交给CPU,CPU根据指定的算法进行调度,分片执行指令。出现顺序错乱的现象正常,因为他们都在同时抢占屏幕。 更多方法: start 线程准备就绪,等待CPU调度 setName 为线程设置名称 getName 获取线程名称 setDaemon 设置为后台线程或前台线程(默认) 如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止 如果是前台线程,主线程执行过程中,前台线程也在进行

python多线程

て烟熏妆下的殇ゞ 提交于 2020-01-08 19:59:08
线程基本使用 #子线程会等待所有的子线程结束后才结束 import threading import time def sing ( ) : for i in range ( 5 ) : print ( "唱歌" ) time . sleep ( 0.5 ) def dance ( ) : for i in range ( 5 ) : print ( "跳舞" ) time . sleep ( 0.5 ) if __name__ == '__main__' : t1 = threading . Thread ( target = sing ) # 注意函数名是没有小括号的 t1 . start ( ) t2 = threading . Thread ( target = dance ) # 注意函数名是没有小括号的 t2 . start ( ) print ( "主线程结束了!" ) 活跃进程数 threadList = threading . enumerate ( ) #查看活跃线程数量 print ( len ( threadList ) ) 线程名称 print ( threading . current_thread ( ) ) 线程传参 元组传递 字典传递 t1 = threading . Thread ( target = sing , args = ( 10 ,

一定要你明白Java中的volatile

限于喜欢 提交于 2020-01-08 09:06:02
摘自: https://www.cnblogs.com/tonyY/p/12158856.html 一定要你明白Java中的volatile 2020-01-07 14:06 兔子托尼啊 阅读( 242) 评论( 0) 编辑 收藏 今天Tony来和大家聊聊Java中关键字 volatile 。 字节码 首先 volatile int a = 3; 和 int a = 3; , 加不加 volatile 关键字,最终生成的字节码都一样的。有兴趣的同学可以试试看看字节码是否一样。 英文解释 Adding volatile to the field does not change Java bytecode that reads or writes the field. It only changes the interpretation of the program by JVM or JIT compilation output if needed. It also influences optimizations. 中文理解 内存屏障的概念是针对CPU架构级别的,需要在JIT编译器生成机器码的时候才能看到。 java内存 讲讲java内存,在java内存中所有的变量都存在与主内存中,每个线程都有自己的工作内存。每个线程中的所用到的变量都是一个副本,都是从主内存中拷贝过来的。

day30

﹥>﹥吖頭↗ 提交于 2020-01-08 01:46:40
GIL(全局解释器锁) 在CPython中,全局解释器锁(GIL)是一个防止多个锁的互斥锁。 本机线程从执行Python字节码一次。这把锁主要是必须的因为CPython的内存管理不是线程安全。(然而,自从GIL存在时,其他功能已逐渐依赖于它所实施的保证。) 基于CPython来研究全局解释器锁 1.GIL本质是一个互斥锁 2.GIL是为了阻止同一个进程内多个线程同时执行(并行) — 单个进程下的多个线程无法实现并行,但能实现并发 3.这把锁主要是因为CPython的内存管理不是"线程安全"的 — 内存管理 — 垃圾回收机制 注意:多个线程过来执行,一旦遇到IO操作,就会立马释放GIL解释器锁,交给下一个先进来的线程 Copyimport time from threading import Thread, current_thread number = 100 def task(): global number number2 = number # time.sleep(1) number = number2 - 1 print(number, current_thread().name) for line in range(100): t = Thread(target=task) t.start() 死锁现象 Copyfrom threading import Lock,

Python36 多线程、多进程的使用场景

对着背影说爱祢 提交于 2020-01-07 23:45:19
多线程与多进程的使用场景 io 操作不占用CPU(从硬盘、从网络、从内存读数据都算io) 计算占用CPU(如1+1计算) python中的线程是假线程,不同线程之间的切换是需要耗费资源的,因为需要存储线程的上下文,不断的切换就会耗费资源。。 python多线程适合io操作密集型的任务(如socket server 网络并发这一类的); python多线程不适合cpu密集操作型的任务,主要使用cpu来计算,如大量的数学计算。 那么如果有cpu密集型的任务怎么办,可以通过多进程来操作(不是多线程)。 假如CPU有8核,每核CPU都可以用1个进程,每个进程可以用1个线程来进行计算。 进程之间不需要使用gil锁,因为进程是独立的,不会共享数据。 进程可以起很多个,但是8核CPU同时只能对8个任务进行操作。 多进程 测试多进程 import multiprocessing import time def run(name): time.sleep(2) print ('heelo',name) if __name__ == '__main__': for i in range(10): #起了10个进程 p = multiprocessing.Process(target=run,args=('bob%s' %i,)) p.start() 执行结果: heelo bob1 heelo

socket选项 SO_REUSEPORT

自古美人都是妖i 提交于 2020-01-07 12:38:51
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 前言 本篇用于记录学习SO_REUSEPORT的笔记和心得,末尾还会提供一个bindp小工具也能为已有的程序享受这个新的特性。 当前Linux网络应用程序问题 运行在Linux系统上网络应用程序,为了利用多核的优势,一般使用以下比较典型的多进程/多线程服务器模型: 单线程listen/accept,多个工作线程接收任务分发,虽CPU的工作负载不再是问题,但会存在: 单线程listener,在处理高速率海量连接时,一样会成为瓶颈 CPU缓存行丢失套接字结构(socket structure)现象严重 所有工作线程都accept()在同一个服务器套接字上呢,一样存在问题: 多线程访问server socket锁竞争严重 高负载下,线程之间处理不均衡,有时高达3:1不均衡比例 导致CPU缓存行跳跃(cache line bouncing) 在繁忙CPU上存在较大延迟 上面模型虽然可以做到线程和CPU核绑定,但都会存在: 单一listener工作线程在高速的连接接入处理时会成为瓶颈 缓存行跳跃 很难做到CPU之间的负载均衡 随着核数的扩展,性能并没有随着提升 比如HTTP CPS(Connection Per Second)吞吐量并没有随着CPU核数增加呈现线性增长: Linux kernel 3.9带来了SO

netty

梦想的初衷 提交于 2020-01-06 17:52:16
1.BIO、NIO 和 AIO 的区别? BIO: 一个连接一个线程,客户端有连接请求时服务器端就需要启动一个线程进行处理。线程开销大。 伪异步 IO: 将请求连接放入线程池,一对多,但线程还是很宝贵的资源。 NIO: 一个请求一个线程,但客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有 I/O 请求时才启动一个线程进行处理。 AIO: 一个有效请求一个线程,客户端的 I/O 请求都是由 OS 先完成了再通知服务器应用去启动线程进行处理。 BIO 是面向流的,NIO 是面向缓冲区的;BIO 的各种流是阻塞的。而 NIO 是非阻塞的;BIO的 Stream 是单向的,而 NIO 的 channel 是双向的。 NIO 的特点: 事件驱动模型、单线程处理多任务、非阻塞 I/O,I/O 读写不再阻塞,而是返回 0、基于 block 的传输比基于流的传输更高效、更高级的 IO 函数 zero-copy、IO 多路复用大大提高了 Java 网络应用的可伸缩性和实用性。基于 Reactor 线程模型。 在 Reactor 模式中,事件分发器等待某个事件或者可应用或个操作的状态发生,事件分发器就把这个事件传给事先注册的事件处理函数或者回调函数,由后者来做实际的读写操作。如在 Reactor 中实现读:注册读就绪事件和相应的事件处理器、事件分发器等待事件、事件到来,激活分发器

8.1Go并发

拜拜、爱过 提交于 2020-01-04 05:20:52
第八章 Go并发 Go语言区别于其他语言的一大特点就是出色的并发性能,最重要的一个特性那就是 go 关键字。 并发场景: UI小姐姐一边开着PS软件,一边微信疯狂的和产品经理打字交流,后台还听着网易云音乐。。 双11当天。。大伙疯狂的访问淘宝网站 CPU从单核向多核发展,计算机程序不该是串行的,浪费资源 串行程序由于IO操作被阻塞,整个程序处于停滞状态,其他IO无关的任务无法执行 并发必要性: 充分利用CPU核心的优势,提高程序执行效率 实现并发的模型: 多进程,多进程是在操作系统层面并发的基本模式,进程间互不影响,但是开销最大,进程由内核管理。 多线程,属于系统层面的并发模式,也是用的最多的有效模式,大多数软件使用多线程,开销小于多进程。 基于回调的非阻塞/异步IO。此架构处于多线程模式的危机,高并发服务器下,多线程会消耗殆尽服务器的内存和CPU资源。而通过事件驱动的方式使用异步IO,尽可能少用线程,降低开销,Node.js就是如此实践,但是此模式编程复杂度较高。 协程,Coroutine是一种用户态线程,寄存于线程中,系统开销极小,可以有效提高线程任务并发性,使用方式简单,结构清晰,避免多线程的缺点。需要编程语言的支持,如不支持,需要用户自行实现调度器。 共享内存系统 是比较常用的并发模式,线程之间通信采用共享内存的方式,程序员需要加锁等操作避免死锁、资源竞争等问题。