进程、线程分别用到的模块是 multiprocessing.Process 和 threading.Thread
方法有 start() join() 等
同时在线程和进程中都可以调用 Queue(主要用put,get) 和Lock(acquire、release)。在进程中虽然各自拥有独立的内存,但是为了防止同时使用输出(CMD,还有桌面??不太确定),还是有机会用到Lock。
另外就是携程! 它其实就是线程的小弟、运行的时候是一个线程假装并发执行多个函数(就像通过yield 分批次执行)
大概就是这个赶脚:
def run(n):
for i in range(n):
print 'running %d'%i
yield i
def work(n):
for i in range(n):
print 'working %d'%i
yield i
r=run(10)
w=work(10)
for i in range(10):
r.next()
w.next()
print i
这种协程可以用 greenlet 来操作,利用其switch() 函数,互相切换(手工)
另外还可以自动切换,根据什么切换呢?? 根据IO,一旦要用到IO则先调用系统IO操作的接口,然后该线程继续往下执行,当系统操作完IO,将数据送到用户内存空间的时候,线程又滚回来操作。【PS: 据说这种用得比较少,因为复杂,还有系统哪里好像也不怎么支持。PPSS:大神说的】
IO操作分为:阻塞,非阻塞,IO多路复用,异步IO
第1,2没什么好说的,第4种就是刚刚上面说的自动切换。
主要说说第三种:
select:
监听N个IO,一旦有情况,系统就会通知,但不告诉你哪个IO有信息
该段代码应该只有python 3以上才能运行,因为2.7的server 和 3.0的server返回的值不一样
#encoding:utf-8
import socket
import select
host = '127.0.0.1'
port = 12345
server = socket.socket()
server.bind((host,port))
server.listen(50)
server.setblocking(False)
inputs = [server,] #监测列表,一开始先监测自己
outputs = []
while 1:
readable,writeable,exceptional = select.select(inputs,outputs,inputs)#读,写,异常监测(监测读列表的异常)
conn = None
addr = None
for r in readable:
if r is server: #如果返回的连接是server,代表来了一个新链接
conn,addr = server.accept()
inputs.append(conn) #将连接进服务器的连接加入监听列表
else:
#conn,addr = server.accept() ,这个当然是错的,应该接收最新发送数据的连接
conn,addr = r.accept()
print conn.recv(1024) #如果监听到除了server以外的连接,则说明该次传输的时数据
poll
select默认只能监听1024,但它没限制,其他同上。
epoll
可以知道是哪个IO有信息
selector 模块:默认使用epoll 如果是windows 则用select
import selectors
def accept(conn,mask):#server 收到新链接的回调函数
new_conn = server.accept()
new_conn.setblocking(False)
sel.register(server,selectors.EVENT_READ,read)
#新链接则
def read(conn,mask):#当监听链接发送时的回调函数
data = conn.recv(1024)
if data:
print(data)
else:
sel.unregister(conn)
#如果没收到数据,表明链接断了,则注销该监听
print("nothing")
server.bind((host,port))
server.listen(50)
server.setblocking(False)
sel = selectors.DefaultSelector()
sel.register(server,selectors.EVENT_READ,accept)
#accept 会在监听到有连接的时候执行
while True:
event = sel.select() #名字是select但有可能是epoll
#默认是阻塞,返回活动连接列表
for key ,mask in event:
callback = key.data
callback(key.fileobj,mask)
#key.fileobj 是文件句柄(相当于上面代码中还没有建立链接的r)