python多线程

并发编程—协程

依然范特西╮ 提交于 2019-12-03 11:26:53
目录 1、什么是协程 2、使用协程的优缺点 3、实现协程的方法 3.1 模块greenlet 3.2 模块gevent 3.2.1 介绍 3.2.2 使用方法 3.2.3 同步与异步 3.2.4 应用举例 1、什么是协程 协程:是单线程下的并发,又称微线程,纤程。 协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的 需要强调的是: 1、python的线程属于内核级别,即有操作系统控制调度(如单线程遇到i/o时间过长,就会被迫交出cpu执行权限,切换其他线程运行) 2、单线程内开启协程,一旦遇到i/o,就会从应用程序级别(而非操作系统)控制切换,以此来提升效率(特别注意:非i/o操作的切换与效率无关) 2、使用协程的优缺点 对比操作系统控制线程的切换,用户在单线程内控制协程的切换 优点: 1、协程的切换开销更小,属于程序级别的切换,操作系统完全感知不到,因而更加轻量级 2、单线程内就可以实现并发的效果,最大限度使用cpu 缺点: 1、协程的本质是单线程下,无法利用多核,可以是一个程序开启多个进程,每个进程内可以开启多个线程,每个线程内可以开启多个协程 2、协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程 总结协程特点: 1、必须在只有一个单线程里实现并发 2、修改共享数据不需要加锁 3、用户程序里自己保存多个控制流的上下文线 4

彻底理解Python多线程中的setDaemon与join【配有GIF示意】

微笑、不失礼 提交于 2019-12-03 07:09:51
在进行Python多线程编程时, join() 和 setDaemon() 是最常用的方法,下面说说两者的用法和区别。 1、join () 例子:主线程A中,创建了子线程B,并且在主线程A中调用了B.join(), 那么, 主线程 A会在调用的地方 阻塞 , 直到子线程 B 完成 操作后,才可以接着往下执行。 2、setDaemon() 例子:主线程A中,创建了子线程B,并且在主线程A中调用了B.setDaemon(), 即:把 主线程 A设置为 守护线程 ,这时候,要是主线程A执行结束了,就 不管子线程 B 是否完成, 一并和主线程A退出。 注意:必须在start() 方法调用之前设置,如果不设置为守护线程,程序会被无限挂起。 3、区别 两者基本是相反的(join主线程等子线程完事【横刀立马】,setDaemon主线程管好自己就可以了,不等子线程完事【义无反顾】)。 4、代码层面理解 # coding:utf-8 import threading import time def get_list_page(): print("get_list_page is start\n") time.sleep(3) print("get_list_page is end\n") def get_detail_page(): print("get_detail_page is start\n

聊聊C10K问题及解决方案

*爱你&永不变心* 提交于 2019-12-03 07:04:30
#0 系列目录# 聊聊远程通信 Java远程通讯技术及原理分析 聊聊Socket、TCP/IP、HTTP、FTP及网络编程 RMI原理及实现 RPC原理及实现 轻量级分布式 RPC 框架 使用 RMI + ZooKeeper 实现远程调用框架 深入浅出SOA思想 微服务、SOA 和 API对比与分析 聊聊同步、异步、阻塞与非阻塞 聊聊Linux 五种IO模型 聊聊IO多路复用之select、poll、epoll详解 聊聊C10K问题及解决方案 #1 C10K问题# 大家都知道 互联网的基础就是网络通信 ,早期的互联网可以说是一个小群体的集合。互联网还不够普及,用户也不多。一台服务器同时在线100个用户估计在当时已经算是大型应用了。所以并不存在什么C10K的难题。互联网的爆发期应该是在www网站,浏览器,雅虎出现后。最早的互联网称之为Web1.0,互联网大部分的使用场景是下载一个Html页面,用户在浏览器中查看网页上的信息。这个时期也不存在C10K问题。 Web2.0时代到来后就不同了,一方面是普及率大大提高了,用户群体几何倍增长。另一方面是互联网不再是单纯的浏览万维网网页,逐渐开始进行交互,而且应用程序的逻辑也变的更复杂,从简单的表单提交,到即时通信和在线实时互动。C10K的问题才体现出来了。 每一个用户都必须与服务器保持TCP连接才能进行实时的数据交互

线程,进程,协程基本理解

妖精的绣舞 提交于 2019-12-03 06:52:07
进程:计算机程序一次执行的实例,由程序数据段PCB组成,是计算机资源分配和调度的基本单位,也是线程的容器。 线程:线程也叫轻量级进程,是程序执行的最小单位,本身只拥有少部分执行必须的资源。 协程:·协程也叫微线程,用户可自己控制协程切换的时机,不再需要陷入系统的内核态。线程和进程都面临着内核态和用户态的切换问题,耗费许多切换时间。 区别: 1)线程共享内存空间,进程内存独立 2)线程之间可直接通信,进程间通信必须通过中间代理 3)同一进程的线程之间可以相互控制,但进程只能控制子进程 4)线程创建很简单,但创建新进程必须对父进程进行一次克隆 5)改变主线陈会影响其他线程,但改变父进程不会影响子进程 GIL:全局解释器锁,系统中同一时间点,只能有一个线程被解释器解释,无法做到并行,无法充分利用多核资源。 python所谓的多线程就类似于单核CPU情况下的多进程编程。 如何解决GIL锁的问题: 1)更换cpython为jpython 2)使用多进程执行多线程任务 3)通过C来实现多线程 互斥锁:多线程时,保证修改的数据为有序修改,不会产生数据修改混乱。 来源: https://www.cnblogs.com/zhanghaibin16/p/11781337.html

python-多进程、多线程实现http 服务器

。_饼干妹妹 提交于 2019-12-03 04:22:58
import socketfrom multiprocessing import Processimport threadingimport redef handle_client(client_socket): """ 处理客户端请求 """ request_data = client_socket.recv(1024).decode('utf-8') request_lines = request_data.splitlines() ret = re.match(r'[^/]+(/[^ ]*)', request_lines[0]) print(">>", ret.group(1)) # 构造响应数据 response_start_line = "HTTP/1.1 200 OK\r\n" response_headers = "Server: My server\r\n" # response_body = "<h1>Python HTTP Test</h1>" f = open('index.html', 'rb') response_body = f.read() f.close() response = response_start_line + response_headers + "\r\n" #+ response_body # 向客户端返回响应数据 client

python多线程与多进程异步事件框架

守給你的承諾、 提交于 2019-12-03 02:53:48
多线程简单实现 #!/usr/bin/env python # -*- coding: UTF-8 -*- import logging import queue import threading from concurrent.futures import ThreadPoolExecutor # 任务:事件 def func_a(a, b): return a + b def func_b(a, b): return a * b def func_c(a, b, c): return a * b - c # 回调函数 def handle_result1(result): print(type(result), result) def handle_result2(result): print(type(result), result) def handle_result3(result): print(type(result), result) class EventEngine(object): # 初始化事件事件驱动引擎 def __init__(self): # 保存事件列表:异步任务队列 self.__eventQueue = queue.Queue() # 引擎开关 self.__active = False # 事件处理字典{'event1': [handler1

Python之路(第四十七篇) 协程

此生再无相见时 提交于 2019-12-03 02:45:09
一、协程介绍 协程:是单线程下的并发,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程: 协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。 协程相比于线程,最大的区别在于,协程不需要像线程那样来回的中断切换,也不需要线程的锁机制,因为线程中断或者锁机制都会对性能问题造成影响,所以协程的性能相比于线程,性能有明显的提高,尤其在线程越多的时候,优势越明显。 协程的好处: 无需线程上下文切换的开销 无需原子操作锁定及同步的开销 "原子操作(atomic operation)是不需要synchronized",所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序是不可以被打乱,或者切割掉只执行部分。视作整体是原子性的核心。 方便切换控制流,简化编程模型 高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题。所以很适合用于高并发处理。 缺点: 无法利用多核资源:协程的本质是个单线程,它不能同时将单个 CPU 的多个核用上,协程需要和进程配合才能运行在多 CPU 上.当然我们日常所编写的绝大部分应用都没有这个必要,除非是 CPU 集型应用。 进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序

Go语言并发与并行--goroutine和channel和deadlock详解

﹥>﹥吖頭↗ 提交于 2019-12-03 02:07:26
概述 进程,线程的概念在操作系统的书上已经有详细的介绍。进程是内存资源管理和cpu调度的执行单元。为了有效利用多核处理器的优势,将进程进一步细分,允许一个进程里存在多个线程,这多个线程还是共享同一片内存空间,但cpu调度的最小单元变成了线程。 那协程又是什么东西,以及与线程的差异性? 协程,可以看作是轻量级的线程。但与线程不同的是,线程的切换是由操作系统控制的,而协程的切换则是由用户控制的。 最早支持协程的程序语言应该是lisp方言scheme里的continuation(续延),续延允许scheme保存任意函数调用的现场,保存起来并重新执行。Lua,C#,python等语言也有自己的协程实现。 Go语言从语言层面上就支持了并发,这与其他语言大不一样,不像以前我们要用Thread库 来新建线程,还要用线程安全的队列库来共享数据。 Go的goroutine goroutinue,本质上就是协程 。但也存在两点不同: goroutine可以实现并行,也就是说,多个协程可以在多个处理器上跑。而协程同一时刻只能在一个处理器上跑(把宿主语言想象成单线程就好了)。 goroutine之间通信是通过channel,而协程通信时通过yield和resume()操作。 以下的程序,我们串行地去执行两次 loop 函数: func loop(){ for i:=0;i<10;i++{ fmt

python-多线程共享全局变量

有些话、适合烂在心里 提交于 2019-12-03 01:53:58
import threadingimport time# 定义一个变量nums = [11, 22]def test1(nums): nums.append(33) print('-----------in test1 num={}---'.format(nums))def test2(): print('-----------in test2 num={}---'.format(nums))def main(): t1 = threading.Thread(target=test1, args=(nums,)) # args 传递参数,要用元组的形式 t2 = threading.Thread(target=test2) t1.start() time.sleep(1) t2.start() time.sleep(1) print('-----------in main Thread num={}---'.format(nums))if __name__ == '__main__': main() 来源: https://www.cnblogs.com/fuyouqiang/p/11770320.html

Flask 开启多进程或多线程

匿名 (未验证) 提交于 2019-12-03 00:13:02
2018-07-15 23:31:20 yang9315 阅读数 7703 更多 分类专栏: python 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接: https://blog.csdn.net/yang9315/article/details/81058394 Flask 默认是单进程,单线程阻塞的任务模式,在项目上线的时候可以通过nginx+gunicorn 的方式部署flask任务 但是在开发的过程中如果想通过延迟的方式测试高并发怎么实现呢,其实非常简单 app.run()中可以接受两个参数,分别是 threaded和 processes,用于开启线程支持和进程支持。 1.threaded : 多线程支持,默认为False,即不开启多线程; 2.processes:进程数量,默认为1. 开启方式: 1 if __name__ == '__main__': 2 app.run(threaded= True) 3 4 # app.run(processes=4) 注意:多进程或多线程只能选择一个,不能同时开启 来源:博客园 作者: 枫飞飞 链接:https://www.cnblogs.com/fengff/p/11636942.html