进程:

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

进程号:

  1. #!usr/bin/env python
  2. #-*-coding:utf-8-*-
  3. # Author calmyan
  4.  
  5. import multiprocessing,threading,time,os
  6. from multiprocessing import Process#从 multprocessing 打开 Process
  7. def info_l(file):
  8. print('当前模块名:',__name__)
  9. print('父进程ID:',os.getppid())
  10. print('进程ID:',os.getpid())
  11. print('\n\n')
  12.  
  13. def f(name):
  14. print('查看:',name)
  15. info_l('相关列表')
  16.  
  17. if __name__ == '__main__':
  18. info_l('主进程相关列表')
  19. p=Process(target=f,args=('当前进程',))
  20. p.start()
  21. p.join()

进程锁:

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

进程之间通讯:

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

进程池:

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

协程:

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

  1. #!usr/bin/env python
  2. #-*-coding:utf-8-*-
  3. # Author calmyan
  4. #python
  5. #2017/6/24 14:03
  6. #__author__='Administrator'
  7. from urllib import request
  8. import gevent,time
  9. from gevent import monkey
  10. monkey.patch_all()#对所有的I/O操作进行标记
  11.  
  12. def f(url):#爬取网页
  13. print('网址: ',url)
  14. resp=request.urlopen(url)#打开网页
  15. data=resp.read()#读取网页
  16. print('网址:[%s]的网页数据大小:[%s]'%(url,len(data)))
  17.  
  18. urls=['https://www.python.org/',
  19. 'https://hao.360.cn/',
  20. 'https://www.yahoo.com/']
  21.  
  22. time_start=time.time()#同步 串行开始时间
  23. for url in urls:
  24. f(url)
  25. print('同步时长:',time.time()-time_start)
  26.  
  27. time_start_asy=time.time()#异步 并行开始时间
  28. gevent.joinall([
  29. gevent.spawn(f,'https://www.python.org/'),
  30. gevent.spawn(f,'https://hao.360.cn/'),
  31. gevent.spawn(f,'https://www.yahoo.com/')
  32. ])
  33. print('异域步时长:',time.time()-time_start_asy)

协程socket_server 实现并发

  1. #!usr/bin/env python
  2. #-*-coding:utf-8-*-
  3. # Author calmyan
  4. #python
  5. #2017/6/24 14:42
  6. #__author__='Administrator'
  7.  
  8. import sys
  9. import socket
  10. import time
  11. import gevent
  12.  
  13. from gevent import socket,monkey
  14. monkey.patch_all()
  15.  
  16. def server(port):
  17. s = socket.socket()#socket 对象
  18. s.bind(('0.0.0.0', port))#服务端,bind IP 端口
  19. s.listen(500)
  20. print('监听中....')
  21. while True:
  22. cli, addr = s.accept()
  23. gevent.spawn(handle_request, cli)#创建一个新协程来
  24.  
  25. def handle_request(conn):
  26. try:
  27. while True:
  28. data = conn.recv(1024)
  29. print("recv:", data)
  30. conn.send(data)
  31. if not data:
  32. conn.shutdown(socket.SHUT_WR)
  33.  
  34. except Exception as ex:
  35. print(ex)
  36. finally:
  37. conn.close()
  38. if __name__ == '__main__':
  39. server(8001)

select :

socket_server

  1. #!usr/bin/env python
  2. #-*-coding:utf-8-*-
  3. # Author calmyan
  4. #python
  5. #2017/6/24 19:34
  6. #__author__='Administrator'
  7.  
  8. import select,socket,sys ,queue
  9.  
  10. s=socket.socket()#实例化一个连接对象
  11. s.setblocking(0)#设置成非阻塞
  12. server_addr=('localhost',9500)#设置绑定的 IP 端口
  13. s.bind(server_addr)#连接对象绑定IP 端口
  14. s.listen(100)#队列 可连接数量
  15. inputs=[s,]#首先要监测本身
  16.  
  17. outputs=[]#发送列表
  18.  
  19. meg_queues={} #发送 连接对象的队列集合 字典
  20.  
  21. while True:
  22. print('监听中......')
  23. readable,writeable,exeptional=select.select(inputs,outputs,inputs)#生成select 对象,返回三个列表 连接,发关,错误
  24.  
  25. for i in readable: #i为一个socket
  26. if i is s:#如果i s 表示有新 连接 进来
  27. conn,client_addr=i.accept()#建立一个新连接
  28. print('接入一个新连接...',client_addr)
  29. conn.setblocking(0)#也设成非阻塞
  30. inputs.append(conn)#加入select,的连接列表,避免出现阻塞
  31. meg_queues[conn]=queue.Queue()#创建一个队列 添加到字典
  32. else:
  33. try:
  34. data=i.recv(1024)#如果不是新连接就收数据
  35. except Exception as e:
  36. print(e)
  37. if data: #如果数据不为空
  38. print('[%s] 发来的数据 [%s]'%(i.getpeername,data))
  39. meg_queues[i].put(data)#当前连接的消息队列加入数据
  40. if i not in outputs:#如果当前连接没有在发送列表内,就加入发送列表
  41. outputs.append(i)
  42. else:
  43. print('客户端已经断开了....')#开始清理工作
  44. if i in outputs:#在发送列表
  45. outputs.remove(i)#在发送列表内删除
  46. inputs.remove(i)#在连接列表内删除
  47. del meg_queues[i]#在队列字典内删除
  48.  
  49. for w in writeable:#循环发送列表
  50. try:
  51. msg=meg_queues[w].get_nowait()#取出队列中的数据,判断
  52. except queue.Empty:#如果数据为空
  53. outputs.remove(w)##从发送列表内删除
  54. else:
  55. w.send(msg)#发送
  56.  
  57. for e in exeptional:#循环错误列表
  58. print('连接[%s]出错!'%e.getpeername)
  59. inputs.remove(e)##从发送列表内删除
  60. if e in outputs:#在发送列表
  61. outputs.remove(e)#在发送列表内删除
  62. e.close()
  63. del meg_queues[e]#在队列字典内删除

socket_client

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

selectors :

  1. #!usr/bin/env python
  2. #-*-coding:utf-8-*-
  3. # Author calmyan
  4. #python
  5. #2017/6/24 21:58
  6. #__author__='Administrator'
  7. import selectors
  8. import socket
  9.  
  10. sel = selectors.DefaultSelector()#生成一个创建一个selectors对象
  11.  
  12. def accept(sock, mask):
  13. conn, addr = sock.accept() # 建立新连接
  14. print('accepted', conn, 'from', addr)
  15. conn.setblocking(False)#设成非阻塞
  16. sel.register(conn, selectors.EVENT_READ, read)#注册 连接,回调函数 read
  17.  
  18. def read(conn, mask):
  19. data = conn.recv(1024) # 接收数据
  20. if data:#不为空
  21. print('echoing', repr(data), 'to', conn)
  22. conn.send(data) # 发送数据
  23. else:#如果为空
  24. print('closing', conn)
  25. sel.unregister(conn)#取消注册
  26. conn.close()#关闭连接
  27.  
  28. server_addr=('localhost',9501)#设置绑定的 IP 端口
  29. sock = socket.socket()#创建一个sock对象
  30. sock.bind(server_addr)#绑定IP 端口
  31. sock.listen(100)
  32. print('监听中...')
  33. sock.setblocking(False)#非阻塞
  34. sel.register(sock, selectors.EVENT_READ, accept)#注册连接 返调函数为accept
  35.  
  36. while True:
  37. events = sel.select()#默认为阻塞模式
  38. for key, mask in events:#如果有连接,接入
  39. callback = key.data#新建连接句柄
  40. 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. http协议返回码

    有五种可能取值:1xx:指示信息--表示请求已接收,继续处理2xx:成功--表示请求已被成功接收.理解.接受3xx:重定向--要完成请求必须进行更进一步的操作4xx:客户端错误--请求有语法错误或请求 ...

  2. Atom相关资料整理

    官网地址 https://atom.io/ Atom 中文社区 https://atom-china.org/ 常用插件 Emmet 这款插件是用来支持zend-coding,Emmet的前身是大名鼎 ...

  3. AWS EC2实例Ubuntu系统设置root用户密码并使用root/ubuntu用户登录

    参考链接:http://www.wangchao.info/1137.html  注意:链接中写的简化了,其中重启服务的命令似乎不太适用,可能是不通用,我下面描述的方式亲测可行,如有其他疑问请留言: ...

  4. JVM内存区域划分及垃圾回收

    第一部分.闲扯+概述 近来在研读<深入理解java虚拟机>一书,读完之后做个小结,算是记录一下自己的学习所得,在成长的路上,只能死磕. 要理解JVM,就要先从其内存区域划分开始,知道其由几 ...

  5. redis.properties

    #### env:${env} redis.maxIdle= ##最小空闲数 redis.minIdle= ##最大连接数:能够同时建立的“最大链接个数” redis.maxTotal= #每次最大连 ...

  6. mysql格式化时间戳为日期

    MySQL中有一个像PHP的date函数一样的日期格式化函数DATE_FORMAT,使用这个函数时,需要像下面例子这样传递一个格式字符串和时间戳 SELECT DATE_FORMAT(NOW(),&q ...

  7. mybatis教程6(逆向工程)

    什么是逆向工程 简单点说,就是通过数据库中的单表,自动生成java代码. Mybatis官方提供了逆向工程,可以针对单表自动生成mybatis代码(mapper.java\mapper.xml\po类 ...

  8. [转]angular2封装material2对话框组件

    本文转自:https://www.jianshu.com/p/da9978e25566 1. 说明 angular-material2自身文档不详,控件不齐,使用上造成了很大的障碍.这里提供一个方案用 ...

  9. Kite(几何+镜面对称)

    C. Kite Time Limit: 1000ms   Case Time Limit: 1000ms   Memory Limit: 65536KB   Vova bought a kite co ...

  10. UserControl VS TemplatedControl

    一:首先来看一下UserControl 熟悉XAML的朋友们都知道,当我们创建一个用户控件的时候,VS会自动为我们生成一个XXX.xaml文件和XXX..xaml.cs文件,XAML文件用于进行控件的 ...