最简单的并发

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并发模型的更多相关文章

  1. 用 Python 理解 Web 并发模型

    用 Python 理解 Web 并发模型 http://www.jianshu.com/users/1b1fde012122/latest_articles   来源:MountainKing 链接: ...

  2. web并发模型

    并发:cpu划分时间片,轮流执行每个请求任务,时间片到期后,换到下一个. 并行:在多核服务器上,每个cpu内核执行一个任务,是真正的并行 IO密集型的应用,由于请求过程中很多时间都是外部IO操作,CP ...

  3. 共享内存 & Actor并发模型哪个更快?

    HI,前几天被.NET圈纪检委@懒得勤快问到共享内存和Actor并发模型哪个速度更快. 前文传送门: 说实在,我内心10w头羊驼跑过...... 先说结论 首先两者对于并发的风格模型不一样. 共享内存 ...

  4. 【并发编程】一文带你读懂深入理解Java内存模型(面试必备)

    并发编程这一块内容,是高级资深工程师必备知识点,25K起如果不懂并发编程,那基本到顶.但是并发编程内容庞杂,如何系统学习?本专题将会系统讲解并发编程的所有知识点,包括但不限于: 线程通信机制,深入JM ...

  5. Java并发指南2:深入理解Java内存模型JMM

    本文转载自互联网,侵删   一:JMM基础与happens-before 并发编程模型的分类 在并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实 ...

  6. python三大web框架Django,Flask,Flask,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架

    Python几种主流框架 从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等. Django: Python We ...

  7. 理解Storm并发

    作者:Jack47 PS:如果喜欢我写的文章,欢迎关注我的微信公众账号程序员杰克,两边的文章会同步,也可以添加我的RSS订阅源. 注:本文主要内容翻译自understanding-the-parall ...

  8. Server Develop (五) Linux并发模型

    Linux并发模型 目前可以实现并发程序的方法有Apache模型(Process Per Connection,简称PPC),TPC(Thread PerConnection)模型,以及select模 ...

  9. Linux并发模型

    Linux并发模型 Linux并发模型 目前可以实现并发程序的方法有Apache模型(Process Per Connection,简称PPC),TPC(Thread PerConnection)模型 ...

随机推荐

  1. jsp文件上传、下载

    一.文件上传 上传文件是Web开发中经常要用到的功能:例如在基于B/S的人事信息管理系统中上传照片,在新闻发布系统中上传图片等等.....要实现文件上传功能,就需要综合利用java中的文件输入和输出相 ...

  2. Spark RDD概念学习系列之Spark的算子的分类(十一)

    Spark的算子的分类 从大方向来说,Spark 算子大致可以分为以下两类: 1)Transformation 变换/转换算子:这种变换并不触发提交作业,完成作业中间过程处理. Transformat ...

  3. #JAVA操作LDAP

    package com.wisdombud.unicom.monitor.ldap; import java.util.ArrayList; import org.slf4j.Logger; impo ...

  4. 关于spring管理hibernate事物

    下面这篇文章对我帮助很大.http://blog.csdn.net/jianxin1009/article/details/9202907

  5. MongoDB学习笔记(一) MongoDB介绍及安装

    转自:http://database.51cto.com/art/201103/247882.htm http://baike.baidu.com/link?url=b6B3dVSCnQauCX-Ep ...

  6. securecrt 连接vmware ubuntu

    折腾了好几天,我只想说shit,吃一堑长一智,和大家分享. SecureCRT连接Linux是使用Ubuntu下的SSH服务,ssh包括客户端和服务端即openssh-client,openssh-s ...

  7. androidstudio can't run git.exe

    今天用android studio从git下载项目的时候遇到一个问题,提示说can't run git.exe 问了下度娘以及谷歌.但是无果,后面捣鼓了一阵,下了一个git windows版本后,在a ...

  8. 图的深度优先搜索算法DFS

    1.问题描写叙述与理解 深度优先搜索(Depth First Search.DFS)所遵循的策略.如同其名称所云.是在图中尽可能"更深"地进行搜索. 在深度优先搜索中,对最新发现的 ...

  9. [ES6] 17. Set

    Es6 provides "Set", it likes array but the data inside should be unqiue. "Set" i ...

  10. IOS使用APNS推送Payload字节数限制导致推送不成功

    这2天须要在推送上加上脚本,找到了badge方法能够加脚本.加上后可是怎么推送也不成功.郁闷了好久.在网上查找相关资料. 最终被我找到原因: "Payload--最多256bytes. &q ...