day10 python学习随笔
2015-12-28 17:10
330 查看
多路复用
Linux中的 select,poll,epoll 都是IO多路复用的机制。
Python
Python中有一个select模块,其中提供了:select、poll、epoll三个方法,分别调用系统的 select,poll,epoll 从而实现IO多路复用。
注意:网络操作、文件操作、终端操作等均属于IO操作,对于windows只支持Socket操作,其他系统支持其他IO操作,但是无法检测 普通文件操作 自动上次读取是否已经变化
#linux: pipes open() socket windows: socket
select方法
select pipes
事件
python线程的事件用于主线程控制其他线程的执行,事件主要提供了三个方法 set、wait、clear。
事件处理的机制:全局定义了一个“Flag”,如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞,如果“Flag”值为True,那么event.wait 方法时便不再阻塞。
clear:将“Flag”设置为False
set:将“Flag”设置为True
Python 进程
进程数据共享
进程各自持有一份数据,默认无法共享数据
Linux中的 select,poll,epoll 都是IO多路复用的机制。
Python
Python中有一个select模块,其中提供了:select、poll、epoll三个方法,分别调用系统的 select,poll,epoll 从而实现IO多路复用。
注意:网络操作、文件操作、终端操作等均属于IO操作,对于windows只支持Socket操作,其他系统支持其他IO操作,但是无法检测 普通文件操作 自动上次读取是否已经变化
#linux: pipes open() socket windows: socket
select方法
select pipes
#ansible源码 import os import sys import shlex import subprocess import select def run_cmd(cmd, live=False, readsize=10): #readsize = 10 cmdargs = shlex.split(cmd) p = subprocess.Popen(cmdargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout = '' stderr = '' rpipes = [p.stdout, p.stderr] while True: rfd, wfd, efd = select.select(rpipes, [], rpipes, 1) if p.stdout in rfd: dat = os.read(p.stdout.fileno(), readsize) if live: sys.stdout.write(dat) stdout += dat if dat == '': rpipes.remove(p.stdout) if p.stderr in rfd: dat = os.read(p.stderr.fileno(), readsize) stderr += dat if live: sys.stdout.write(dat) if dat == '': rpipes.remove(p.stderr) # only break out if we've emptied the pipes, or there is nothing to # read from and the process has finished. if (not rpipes or not rfd) and p.poll() is not None: break # Calling wait while there are still pipes to read can cause a lock elif not rpipes and p.poll() == None: p.wait() return p.returncode, stdout, stderr
#!/usr/bin/env python # -*- coding:utf-8 -*- import select import threading import sys while True: readable, writeable, error = select.select([sys.stdin,],[],[],1) if sys.stdin in readable: print 'select get stdin',sys.stdin.readline() 利用select监听终端操作实例
#!/usr/bin/env python # -*- coding:utf-8 -*- import socket import select sk1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sk1.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sk1.bind(('127.0.0.1',8002)) sk1.listen(5) sk1.setblocking(0) inputs = [sk1,] while True: readable_list, writeable_list, error_list = select.select(inputs, [], inputs, 1) for r in readable_list: # 当客户端第一次连接服务端时 if sk1 == r: print 'accept' request, address = r.accept() request.setblocking(0) inputs.append(request) # 当客户端连接上服务端之后,再次发送数据时 else: received = r.recv(1024) # 当正常接收客户端发送的数据时 if received: print 'received data:', received # 当客户端关闭程序时 else: inputs.remove(r) sk1.close() 利用select实现伪同时处理多个Socket客户端请求:服务端
#!/usr/bin/env python # -*- coding:utf-8 -*- import socket import select sk1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sk1.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sk1.bind(('127.0.0.1',8002)) sk1.listen(5) sk1.setblocking(0) inputs = [sk1,] while True: readable_list, writeable_list, error_list = select.select(inputs, [], inputs, 1) for r in readable_list: # 当客户端第一次连接服务端时 if sk1 == r: print 'accept' request, address = r.accept() request.setblocking(0) inputs.append(request) # 当客户端连接上服务端之后,再次发送数据时 else: received = r.recv(1024) # 当正常接收客户端发送的数据时 if received: print 'received data:', received # 当客户端关闭程序时 else: inputs.remove(r) sk1.close() 利用select实现伪同时处理多个Socket客户端请求:服务端此处的Socket服务端相比与原生的Socket,他支持当某一个请求不再发送数据时,服务器端不会等待而是可以去处理其他请求的数据。但是,如果每个请求的耗时比较长时,select版本的服务器端也无法完成同时操作。
事件
python线程的事件用于主线程控制其他线程的执行,事件主要提供了三个方法 set、wait、clear。
事件处理的机制:全局定义了一个“Flag”,如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞,如果“Flag”值为True,那么event.wait 方法时便不再阻塞。
clear:将“Flag”设置为False
set:将“Flag”设置为True
#!/usr/bin/env python # -*- coding:utf-8 -*- import threading def do(event): print 'start' event.wait() print 'execute' event_obj = threading.Event() for i in range(10): t = threading.Thread(target=do, args=(event_obj,)) t.start() event_obj.clear() inp = raw_input('input:') if inp == 'true': event_obj.set()
Python 进程
from multiprocessing import Process import threading import time def foo(i): print 'say hi',i for i in range(10): p = Process(target=foo,args=(i,)) p.start()注意:由于进程之间的数据需要各自持有一份,所以创建进程需要的非常大的开销。
进程数据共享
进程各自持有一份数据,默认无法共享数据
相关文章推荐
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- install and upgrade scrapy
- Scrapy的架构介绍
- Centos6 编译安装Python
- 使用Python生成Excel格式的图片
- 让Python文件也可以当bat文件运行
- [Python]推算数独
- Python中zip()函数用法举例
- Python中map()函数浅析
- Python将excel导入到mysql中
- Python在CAM软件Genesis2000中的应用
- 使用Shiboken为C++和Qt库创建Python绑定
- FREEBASIC 编译可被python调用的dll函数示例
- Python 七步捉虫法