用python理解web并发模型
最简单的并发
import socket response = 'HTTP/1.1 200 OK\r\nConnection:Close\r\nContent-Length:11\r\n\r\nHello World' server = socket.socket()
server.bind(('0.0.0.0', 9527))
server.listen(1024) while True:
client, clientaddr = server.accept() #等待客户端连接,阻塞
request = client.recv(1024) #等待客户端面消息,阻塞
client.send(response) #可能会阻塞
client.close()
虽然可以处理很多请求,但它依然是一个请求一个请求执行的,而且有两个阻塞的地方,还有一个可能会阻塞的地方,为什么会是可能阻塞,在内核的socket的实现中,有一个read buffer,还有一个write buffer,过程应该是这样的:

多进程
显然,每个请求对应一个进程的话,可以解决阻塞的问题,但是进程太耗资源,而且每个进程都是独立的,无法共享,进程切换成本也高。
import socket
import signal
import multiprocessing response = 'HTTP/1.1 200 OK\r\nConnection:Close\r\nContent-Length:11\r\n\r\nHello World' server = socket.socket()
server.setsockopt(socket.SOL.SOCKET, socket.SO_REUSEADDR, 1)
server.bind(('0.0.0.0', 9527))
server.listen(1024) def handler(client):
request = client.recv(1024)
client.send(response)
client.close() signal.signal(signal.SIGCHLD, signal.SIG_IGN) #多进程里的子进程执行完后并不会死掉,会变成僵尸进程,必须等到主进程挂掉后,才会死掉,这句可以解决这个问题 while True:
client, addr = server.accetp()
process = multiprocessing.Process(target=handler, args=(client,))
process.start()
Prefork
如上面的多进程,如果请求数多,资源占用无法控制;可以分配和cpu核数一样的进程数来有效控制资源占用
import socket
import multiprocessing response = 'HTTP/1.1 200 OK\r\nConnection:Close\r\nContent-Length:11\r\n\r\nHello World' server = socket.socket()
server.bind(('0.0.0.0', 9527))
server.listen(1024) def handler():
while True:
client, addr = server.accept()
request = client.recv(1024)
client.send(response)
client.close() processors = 8
for i in range(0, processors):
process = multiprocessing.Process(target=handler, args=())
process.start()
线程池
import queue
import socket
import threading response = 'HTTP/1.1 200 OK\r\nConnection:Close\r\nContent-Length:11\r\n\r\nHello World' server = socket.socket()
server.bind(('0.0.0.0', 9527))
server.listen(1024) def handler(queue):
while True:
client = queue.get()
request = client.recv(1024)
client.send(response)
client.close() queue_list = queue.Queue()
processors = 8 for i in range(0, processors):
thread = threading.Thread(target=handler, args=(queue_list,))
thread.daemon = True
thread.start() while True:
client, clientaddr = server.accept()
queue_list.put(client)
线程占用的资源比较少,因为资源可以共享, 但是要考虑线程安全问题和锁的性能, 而且python的解释器有GIL, 导致不能有效利用多核CPU。
epoll
import select
import select response = 'HTTP/1.1 200 OK\r\nConnection:Close\r\nContent-Length:11\r\n\r\nHello World' server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setblocking(False)
server_address = ('localhost', 9527)
server.bind(server_address)
server.listen(1024) READ_ONLY = select.EPOLLIN | select.EPOLLPRI
epoll = select.epoll()
epoll.register(server, READ_ONLY)
timeout = 60
fd_to_socket = {server.fileno(): server} while True:
events = epoll.poll(timeout)
for fd, flag in events:
sock = fd_to_socket[fd]
if flag and READ_ONLY:
if sock is server:
conn, client_address = sock.accept()
conn.setblocking(False)
fd_to_socket[conn.fileno()] = conn
epoll.register(conn, READ_ONLY)
else:
request = sock.recv(1024)
sock.send(response)
sock.close()
del fd_to_socket[fd]
用python理解web并发模型的更多相关文章
- 用 Python 理解 Web 并发模型
用 Python 理解 Web 并发模型 http://www.jianshu.com/users/1b1fde012122/latest_articles 来源:MountainKing 链接: ...
- web并发模型
并发:cpu划分时间片,轮流执行每个请求任务,时间片到期后,换到下一个. 并行:在多核服务器上,每个cpu内核执行一个任务,是真正的并行 IO密集型的应用,由于请求过程中很多时间都是外部IO操作,CP ...
- 共享内存 & Actor并发模型哪个更快?
HI,前几天被.NET圈纪检委@懒得勤快问到共享内存和Actor并发模型哪个速度更快. 前文传送门: 说实在,我内心10w头羊驼跑过...... 先说结论 首先两者对于并发的风格模型不一样. 共享内存 ...
- 【并发编程】一文带你读懂深入理解Java内存模型(面试必备)
并发编程这一块内容,是高级资深工程师必备知识点,25K起如果不懂并发编程,那基本到顶.但是并发编程内容庞杂,如何系统学习?本专题将会系统讲解并发编程的所有知识点,包括但不限于: 线程通信机制,深入JM ...
- Java并发指南2:深入理解Java内存模型JMM
本文转载自互联网,侵删 一:JMM基础与happens-before 并发编程模型的分类 在并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实 ...
- python三大web框架Django,Flask,Flask,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架
Python几种主流框架 从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等. Django: Python We ...
- 理解Storm并发
作者:Jack47 PS:如果喜欢我写的文章,欢迎关注我的微信公众账号程序员杰克,两边的文章会同步,也可以添加我的RSS订阅源. 注:本文主要内容翻译自understanding-the-parall ...
- Server Develop (五) Linux并发模型
Linux并发模型 目前可以实现并发程序的方法有Apache模型(Process Per Connection,简称PPC),TPC(Thread PerConnection)模型,以及select模 ...
- Linux并发模型
Linux并发模型 Linux并发模型 目前可以实现并发程序的方法有Apache模型(Process Per Connection,简称PPC),TPC(Thread PerConnection)模型 ...
随机推荐
- algorithm@ Shortest Path in Directed Acyclic Graph (O(|V|+|E|) time)
Given a Weighted Directed Acyclic Graph and a source vertex in the graph, find the shortest paths fr ...
- 编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异
编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异 题目挺绕口的.C++ 11的好东西不算太多,但变参模板(Variadic Template)肯定是其中耀眼的一 ...
- [cocos2d-x]File文件的IO读写处理
转载:http://blog.csdn.net/chiuan/article/details/8618411 为了保存自定义数据文件,需要保存文件和读取文件,也就是File的IO处理: 针对cocos ...
- HDU 5821 Ball (贪心)
Ball 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5821 Description ZZX has a sequence of boxes nu ...
- 【C语言】-一维数组
数组: 数组是一系列相同类型的有序数据的集合,数组中的每一个元素都是同一个数据类型,所有元素共用一个名字,用下标来区别数组中的每一个元素. C语言中,数组属于构造数据类型.一个数组中含有多个数组元素, ...
- C#命名管道通信
C#命名管道通信 最近项目中要用c#进程间通信,以前常见的方法包括RMI.发消息等.但在Windows下面发消息需要有窗口,我们的程序是一个后台运行程序,发消息不试用.RMI又用的太多了,准备用管道通 ...
- FZU 2082 过路费 (树链剖分 修改单边权)
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2082 树链剖分模版题,求和,修改单边权. #include <iostream> #include ...
- myGeneration代码生成器
转自:http://www.cnblogs.com/leitwolf/archive/2007/07/27/833255.html http://blog.csdn.net/happyhippy/ar ...
- jsp页面用el表达式获取枚举的code
jsp页面用el表达式获取枚举的code <c:set var="D_BUSINESS" value="<%=DeptEnum.D_BUSINESS%> ...
- 【转】Rails 3.1错误-Could not find a JavaScript runtime及execjs和therubyracer介绍
转自:http://rubyer.me/blog/740/ Rails 3.1错误 /gems/execjs-1.1.2/lib/ execjs/runtimes.rb:43:in `autodete ...