进程:

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
import multiprocessing,threading,time def run(name):
t=threading.Thread(target=run2)#创建新线程
t.start()
print('进程[%s],打印中...'%name)
time.sleep(1) def run2():
print(threading.get_ident())#打印线程ID
time.sleep(2) if __name__ == '__main__':
for i in range(10):
p=multiprocessing.Process(target=run,args=('第[%s]个进程'%i,))#创建新进程
p.start()

进程号:

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan import multiprocessing,threading,time,os
from multiprocessing import Process#从 multprocessing 打开 Process
def info_l(file):
print('当前模块名:',__name__)
print('父进程ID:',os.getppid())
print('进程ID:',os.getpid())
print('\n\n') def f(name):
print('查看:',name)
info_l('相关列表') if __name__ == '__main__':
info_l('主进程相关列表')
p=Process(target=f,args=('当前进程',))
p.start()
p.join()

进程锁:

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan from multiprocessing import Process,Lock # Lock 进程锁通讯中间件 def f(lock,i):
lock.acquire()#进程锁
print('第[%s]个进程'%i)
lock.release()#解锁
if __name__ =='__main__':
lock=Lock()#进程锁对象
for i in range(10):
p=Process(target=f,args=(lock,i)).start()

进程之间通讯:

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan import multiprocessing,queue,threading
from multiprocessing import Process,Queue # Queue 进程通讯中间件 ''' 线程 之间共享队列
def f():
q.put([1,None,'加入数据'])#队列
if __name__ =='__main__':
q=queue.Queue()#线程队列
#q=Queue()#进程队列
p=threading.Thread(target=f,)#创建线程
p.start()
print(q.get())#输出,取出的
p.join()
'''
def f(q):#存入q对象
q.put([1,None,'加入数据'])#队列
if __name__ =='__main__':
q=Queue()#进程队列
p=Process(target=f,args=(q,))#创建进程
p.start()
print(q.get())#输出,取出的
p.join()
 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
import os
from multiprocessing import Process,Pipe,Manager # Pipe 管道 进程通讯中间件 def f(d,l):
d[os.getpid()]=os.getpid()#修改字典
l.append(os.getpid())#添加列表内容
print(d)
print(l) if __name__ =='__main__':
with Manager() as manager:
d=manager.dict()#创建一个进程之间可修改的字典
l=manager.list(range(5))#创建一个进程之间可修改的列表
p_list=[]#join使用
for i in range(10):
p=Process(target=f,args=(d,l))#创建进程传入数据,
p.start()
p_list.append(p)
for r in p_list:#等待进程完成
r.join()
print(d)
print(l)
 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan from multiprocessing import Process,Pipe # Pipe 管道 进程通讯中间件 def f(conn):#存入conn对象
conn.send(['子进程发送信息','....'])
print('收到父进程的信息:',conn.recv())
conn.close()
if __name__ =='__main__':
parent_conn,child_conn=Pipe()#生成一个管道,返回两个值,管理双端
p=Process(target=f,args=(child_conn,))#创建进程
p.start()
print('收到子进程的信息:',parent_conn.recv())
parent_conn.send(['父进程发送信息'])
p.join()

进程池:

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
#__author__=2017/6/23
import time,os
from multiprocessing import Process,Lock,Pool # Pool 进程池通讯中间件 def Foo(i):
print('第[%s]个进程,ID:'%i,os.getpid())
time.sleep(3)
return i+100
def Bar(arg):
print('回调>>>>:',arg,os.getpid())
if __name__ =='__main__':
#pool=Pool(processes=5)#定义一个进程池 表示允许进程池同时放入5个进程
pool=Pool(5)#定义一个进程池 表示允许进程池同时放入5个进程
for i in range(10):
#pool.apply(func=Foo,args=(i,))#使用进程池创建进程 串行
#pool.apply_async(func=Foo,args=(i,))#使用进程池创建进程 并行
pool.apply_async(func=Foo,args=(i,),callback=Bar)#回调 print('结束')
#pool.join()
pool.close()#一定要先关闭进程池
pool.join()#后进行join

协程:

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
#python
#2017/6/24 10:10
#__author__='Administrator' import time
import queue
def consumer(name):#消费者函数
print('[%s]消费产品中.......'%name)
while True:
new_b=yield #跳转点
print('[%s] 消费 [%s]'%(name,new_b))
def producer():#生产者函数
r=con.__next__()
r2=con2.__next__()
n=0
while n<10:
n+=1
con.send(n)#发送给消费者
con2.send(n)
print('\033[32;1m[生产者]\033[0m生产产品[%s]'%n) if __name__=='__main__':
con=consumer('消费者A')
con2=consumer('消费者B')
p=producer()
 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
#python
#2017/6/24 10:31
#__author__='Administrator'
#import greenlet
from greenlet import greenlet def test1():
print('函数一: 12')
ger2.switch()#进行协程切换
print('函数一: 34')
ger2.switch() def test2():
print('函数二: 56')
ger1.switch()
print('函数二: 78')
ger1.switch() ger1=greenlet(test1)#创建协程
ger2=greenlet(test2)
ger1.switch()
 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
#python
#2017/6/24 10:47
#__author__='Administrator' import gevent
def func1():
print('func1 reading....')
gevent.sleep(2)
print('func1 reading two.. end') def func2():
print('func2 reading....')
gevent.sleep(0)
print('func2 reading two.. end')
def func3():
print('func3 reading....')
gevent.sleep(1)
print('func3 reading two.. end') gevent.joinall([
gevent.spawn(func1),
gevent.spawn(func2),
gevent.spawn(func3)
])

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
#python
#2017/6/24 14:03
#__author__='Administrator'
from urllib import request
import gevent,time
from gevent import monkey
monkey.patch_all()#对所有的I/O操作进行标记 def f(url):#爬取网页
print('网址: ',url)
resp=request.urlopen(url)#打开网页
data=resp.read()#读取网页
print('网址:[%s]的网页数据大小:[%s]'%(url,len(data))) urls=['https://www.python.org/',
'https://hao.360.cn/',
'https://www.yahoo.com/'] time_start=time.time()#同步 串行开始时间
for url in urls:
f(url)
print('同步时长:',time.time()-time_start) time_start_asy=time.time()#异步 并行开始时间
gevent.joinall([
gevent.spawn(f,'https://www.python.org/'),
gevent.spawn(f,'https://hao.360.cn/'),
gevent.spawn(f,'https://www.yahoo.com/')
])
print('异域步时长:',time.time()-time_start_asy)

协程socket_server 实现并发

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
#python
#2017/6/24 14:42
#__author__='Administrator' import sys
import socket
import time
import gevent from gevent import socket,monkey
monkey.patch_all() def server(port):
s = socket.socket()#socket 对象
s.bind(('0.0.0.0', port))#服务端,bind IP 端口
s.listen(500)
print('监听中....')
while True:
cli, addr = s.accept()
gevent.spawn(handle_request, cli)#创建一个新协程来 def handle_request(conn):
try:
while True:
data = conn.recv(1024)
print("recv:", data)
conn.send(data)
if not data:
conn.shutdown(socket.SHUT_WR) except Exception as ex:
print(ex)
finally:
conn.close()
if __name__ == '__main__':
server(8001)

select :

socket_server

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
#python
#2017/6/24 19:34
#__author__='Administrator' import select,socket,sys ,queue s=socket.socket()#实例化一个连接对象
s.setblocking(0)#设置成非阻塞
server_addr=('localhost',9500)#设置绑定的 IP 端口
s.bind(server_addr)#连接对象绑定IP 端口
s.listen(100)#队列 可连接数量
inputs=[s,]#首先要监测本身 outputs=[]#发送列表 meg_queues={} #发送 连接对象的队列集合 字典 while True:
print('监听中......')
readable,writeable,exeptional=select.select(inputs,outputs,inputs)#生成select 对象,返回三个列表 连接,发关,错误 for i in readable: #i为一个socket
if i is s:#如果i 是s 表示有新 连接 进来
conn,client_addr=i.accept()#建立一个新连接
print('接入一个新连接...',client_addr)
conn.setblocking(0)#也设成非阻塞
inputs.append(conn)#加入select,的连接列表,避免出现阻塞
meg_queues[conn]=queue.Queue()#创建一个队列 添加到字典
else:
try:
data=i.recv(1024)#如果不是新连接就收数据
except Exception as e:
print(e)
if data: #如果数据不为空
print('[%s] 发来的数据 [%s]'%(i.getpeername,data))
meg_queues[i].put(data)#当前连接的消息队列加入数据
if i not in outputs:#如果当前连接没有在发送列表内,就加入发送列表
outputs.append(i)
else:
print('客户端已经断开了....')#开始清理工作
if i in outputs:#在发送列表
outputs.remove(i)#在发送列表内删除
inputs.remove(i)#在连接列表内删除
del meg_queues[i]#在队列字典内删除 for w in writeable:#循环发送列表
try:
msg=meg_queues[w].get_nowait()#取出队列中的数据,判断
except queue.Empty:#如果数据为空
outputs.remove(w)##从发送列表内删除
else:
w.send(msg)#发送 for e in exeptional:#循环错误列表
print('连接[%s]出错!'%e.getpeername)
inputs.remove(e)##从发送列表内删除
if e in outputs:#在发送列表
outputs.remove(e)#在发送列表内删除
e.close()
del meg_queues[e]#在队列字典内删除

socket_client

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
#python
#2017/6/24 19:23
#__author__='Administrator' import socket server_addr=('localhost',9500)#设置绑定的 IP 端口
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(server_addr)
while True:
msg = bytes(input(">>:"),encoding="utf8")#定义一个数据 消息
if msg:
s.sendall(msg)#发送数据
else:
print('不能为空')
continue
data = s.recv(1024)#收数据(读数据)
#print(data) print('Received', repr(data.decode()))
s.close()

selectors :

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
#python
#2017/6/24 21:58
#__author__='Administrator'
import selectors
import socket sel = selectors.DefaultSelector()#生成一个创建一个selectors对象 def accept(sock, mask):
conn, addr = sock.accept() # 建立新连接
print('accepted', conn, 'from', addr)
conn.setblocking(False)#设成非阻塞
sel.register(conn, selectors.EVENT_READ, read)#注册 连接,回调函数 read def read(conn, mask):
data = conn.recv(1024) # 接收数据
if data:#不为空
print('echoing', repr(data), 'to', conn)
conn.send(data) # 发送数据
else:#如果为空
print('closing', conn)
sel.unregister(conn)#取消注册
conn.close()#关闭连接 server_addr=('localhost',9501)#设置绑定的 IP 端口
sock = socket.socket()#创建一个sock对象
sock.bind(server_addr)#绑定IP 端口
sock.listen(100)
print('监听中...')
sock.setblocking(False)#非阻塞
sel.register(sock, selectors.EVENT_READ, accept)#注册连接 返调函数为accept while True:
events = sel.select()#默认为阻塞模式
for key, mask in events:#如果有连接,接入
callback = key.data#新建连接句柄
callback(key.fileobj, mask)

事件驱动与异步IO

服务器处理模型的程序时,有以下几种模型:
(1)每收到一个请求,创建一个新的进程,来处理该请求;
(2)每收到一个请求,创建一个新的线程,来处理该请求;
(3)每收到一个请求,放入一个事件列表,让主进程通过非阻塞I/O方式来处理请求
 
第(1)中方法,由于创建新的进程的开销比较大,所以,会导致服务器性能比较差,但实现比较简单。
第(2)种方式,由于要涉及到线程的同步,有可能会面临死锁等问题。
第(3)种方式,在写应用程序代码时,逻辑比前面两种都复杂。
综合考虑各方面因素,一般普遍认为第(3)种方式是大多数网络服务器采用的方式
 
事件驱动编程是一种编程范式,这里程序的执行流由外部事件来决定。它的特点是包含一个事件循环,当外部事件发生时使用回调机制来触发相应的处理。另外两种常见的编程范式是(单线程)同步以及多线程编程。

python第五十三天--进程,协程.select.异步I/O...的更多相关文章

  1. python 自动化之路 day 10 协程、异步IO、队列、缓存

    本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 RabbitMQ队列 Redis\Memcached缓存 Paramiko SSH Twsited网络框架 引子 到目 ...

  2. python之并发编程(线程\进程\协程)

    一.进程和线程 1.进程 假如有两个程序A和B,程序A在执行到一半的过程中,需要读取大量的数据输入(I/O操作),而此时CPU只能静静地等待任务A读取完数据才能继续执行,这样就白白浪费了CPU资源.是 ...

  3. Python【第十篇】协程、异步IO

    大纲 Gevent协程 阻塞IO和非阻塞IO.同步IO和异步IO的区别 事件驱动.IO多路复用(select/poll/epoll) 1.协程 1.1协程的概念 协程,又称微线程,纤程.英文名Coro ...

  4. 第十一章:Python高级编程-协程和异步IO

    第十一章:Python高级编程-协程和异步IO Python3高级核心技术97讲 笔记 目录 第十一章:Python高级编程-协程和异步IO 11.1 并发.并行.同步.异步.阻塞.非阻塞 11.2 ...

  5. Day10 - Python协程、异步IO、redis缓存、rabbitMQ队列

    Python之路,Day9 - 异步IO\数据库\队列\缓存   本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitM ...

  6. 文成小盆友python-num11-(1) 线程 进程 协程

    本节主要内容 线程补充 进程 协程 一.线程补充 1.两种使用方法 这里主要涉及两种使用方法,一种为直接使用,一种为定义自己的类然后继承使用如下: 直接使用如下: import threading d ...

  7. Python协程、异步IO

    本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitMQ队列 Redis\Memcached缓存 Paramiko SS ...

  8. python协程与异步协程

    在前面几个博客中我们一一对应解决了消费者消费的速度跟不上生产者,浪费我们大量的时间去等待的问题,在这里,针对业务逻辑比较耗时间的问题,我们还有除了多进程之外更优的解决方式,那就是协程和异步协程.在引入 ...

  9. 进击的Python【第十章】:Python的高级应用(多进程,进程间通信,协程与异步,牛逼的IO多路复用)

    Python的socket高级应用(多进程,协程与异步) 一.多进程multiprocessing multiprocessing is a package that supports spawnin ...

随机推荐

  1. 基于httpclient的效率优化

    1.背景 我们有个业务,会调用其他部门提供的一个基于http的服务,日调用量在千万级别.使用了httpclient来完成业务.之前因为qps上不去,就看了一下业务代码,并做了一些优化,记录在这里. 先 ...

  2. python 打包exe

    下载及安装:pip install pyinstaller 执行命令: pyinstaller -F xxx.py pyinstaller --onefile meng.py 可以运行的exe文件位于 ...

  3. Rsync文件同步工具

    前段时间因公司需求,需要把备份的文件进行同步保存,后面就想到了我们大家都最熟悉的文件同步工作Rsync,于是就捣鼓了一下午时间,然后总结了下大概过程和参数详情. 首先了解了下rsync同步的大致原理: ...

  4. Enumerable转换为DataTable

    今天在项目组公共类库中发现一个 Enumerable类型转换为DataTable,写的挺精简的,拿出来跟大家共享一下. using System; using System.Collections.G ...

  5. MRTG在Windows平台的安装及使用

    MRTG (Multi Router Traffic Grapher)是一款监控网络流量负载的免费软件,目前利用MRTG已经开发出了各式各样的统计系统: 1.系统资源负载统计,例如:磁盘空间.CPU负 ...

  6. Beego学习笔记

    Beego学习笔记 Go 路由(Controller) 路由就是根据用户的请求找到需要执行的函数或者controller. Get /v1/shop/nike ShopController Get D ...

  7. python 浅析模块,包及其相关用法

    今天买了一本关于模块的书,说实话,模块真的太多了,小编许多也不知道,要是把模块全讲完,可能得出本书了,所以小编在自己有限的能力范围内在这里浅析一下自己的见解,同时讲讲几个常用的模块. 这里是2018. ...

  8. 配置IIS的负载均衡

    在大型Web应用系统中,由于请求的数据量过大以及并发的因素,导致Web系统会出现宕机的现象,解决这一类问题的方法我个人觉得主要在以下几个方面: 1.IIS 负载均衡. 2.数据库 负载均衡. 3.系统 ...

  9. JavaWeb学习(二十九)———— 事务

    一.事务的概念 事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功. 例如:A——B转帐,对应于如下两条sql语句  update from account set mone ...

  10. hexo自动部署到git、ftp(虚拟主机等)、云服务器的方式

    自动部署很有用,当你写完文章后,直接使用hexo d就可以自动更新你的网站了 部署到git 首先你需要在你的blog下安装git deployer插件:npm install hexo-deploye ...