进程:

 #!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. 关于 Nginx 配置 WebSocket 400 问题

    今天把项目升级了 asp.net core 到 2.1 的版本,使用了 signalr  的功能,由于阿里云不支持 websocket 协议,所以使用了 nginx 代理方式来解决,后续就报了一个登陆 ...

  2. 11个教程中不常被提及的JavaScript小技巧

    这次我们主要来分享11个在日常教程中不常被提及的JavaScript小技巧,他们往往在我们的日常工作中经常出现,但是我们又很容易忽略. 1.过滤唯一值 Set类型是在ES6中新增的,它类似于数组,但是 ...

  3. 当Elasticsearch遇见Kafka

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由michelmu发表于云+社区专栏 Elasticsearch作为当前主流的全文检索引擎,除了强大的全文检索能力和高扩展性之外,对多种 ...

  4. 如何做自己的服务监控?spring boot 2.x服务监控揭秘

    Actuator是spring boot项目中非常强大一个功能,有助于对应用程序进行监视和管理,通过 restful api请求来监管.审计.收集应用的运行情况,针对微服务而言它是必不可少的一个环节. ...

  5. 趁webpack5还没出,先升级成webpack4吧

    上一次将webpack1升级到3,也仅是 半年前,前端工具发展变化太快了,如今webpack4已经灰常稳定,传说性能提升非常高,值得升级. 一直用着的webpack3越来越慢,一分多钟的编译时间简直不 ...

  6. 【学习笔记】深入理解async/await

    参考资料:理解javaScript中的async/await,感谢原文作者的总结,本文在理解的基础上做了一点小小的修改,主要为了加深自己的知识点掌握 学完了Promise,我们知道可以用then链来解 ...

  7. scikit-learn入门导航

    scikit-learn是一个非常强大的机器学习库, 提供了很多常见机器学习算法的实现. scikit-learn可以通过pip进行安装: pip install -U scikit-learn 不过 ...

  8. 关于EF实体类的一点思考

    在EF中修改一条记录时,一般是先查出该条记录,然后再通过TryUpdateModel或其他方式更新对应的属性.但我很讨厌这种要更新一条记录时,还要先去把记录查询出来的做法.我喜欢像sql语句那样的直接 ...

  9. 动态规划法(四)0-1背包问题(0-1 Knapsack Problem)

      继续讲故事~~   转眼我们的主人公丁丁就要离开自己的家乡,去大城市见世面了.这天晚上,妈妈正在耐心地帮丁丁收拾行李.家里有个最大能承受20kg的袋子,可是妈妈却有很多东西想装袋子里,已知行李的编 ...

  10. DotNetCore学习-2.程序启动

    新创建的ASP.NET Core程序中包含两个文件,分别是Program.Startup.其中,Program中Main方法是整个应用程序的入口,该方法如下: var host = WebHost.C ...