python單線程解決並發
阿新 • • 發佈:2019-02-04
utf-8 alex pre 取數據 obj locking code .com ioerror
1.單線程解決並發
方式一
import socket import select # 百度創建連接:非阻塞 client1 = socket.socket() client1.setblocking(False) try: client1.connect(('www.baidu.com', 80)) except BlockingIOError as e: pass # 搜狗創建連接:非阻塞 client2 = socket.socket() client2.setblocking(False) try: client2.connect(('www.sogou.com', 80)) except BlockingIOError as e: pass # GitHub創建連接:非阻塞 client3 = socket.socket() client3.setblocking(False) try: client3.connect(('www.github.com', 80)) except BlockingIOError as e: pass # 創建socket列表:socket_list socket_list = [client1, client2, client3] # 創建connect列表:conn_list conn_list = [client1, client2, client3] while True: rlist, wlist, elist = select.select(socket_list, conn_list, [], 0.005) # rlist中表示已近獲取數據的socket對象 # wlist中表示已經連接成功的socket對象 # elist中表示出現錯誤的socket對象 for sk in wlist: if sk == client1: sk.sendall(b'GET /s?wd=alex HTTP/1.0\r\nhost:www.baidu.com\r\n\r\n') elif sk == client2: sk.sendall(b'GET /web?query=fdf HTTP/1.0\r\nhost:www.sogou.com\r\n\r\n') else: sk.sendall(b'GET /s?wd=alex HTTP/1.0\r\nhost:www.oldboyedu.com\r\n\r\n') conn_list.remove(sk) for sk in rlist: chunk_list = [] while True: try: chunk = sk.recv(8096) if not chunk: break chunk_list.append(chunk) except BlockingIOError as e: break body = b''.join(chunk_list) # print(body.decode('utf-8')) print('------------>', body) sk.close() socket_list.remove(sk) if not socket_list: break
方式二
import socket import select class Req(object): def __init__(self,sk,func): self.sock = sk self.func = func def fileno(self): return self.sock.fileno() class Nb(object): def __init__(self): self.conn_list = [] self.socket_list = [] def add(self,url,func): # 創建socket客戶端 client = socket.socket() # 非阻塞 client.setblocking(False) try: # 創建連接 client.connect((url, 80)) # 異常處理 except BlockingIOError as e: pass obj = Req(client,func) # 連接列表 self.conn_list.append(obj) # socket列表 self.socket_list.append(obj) def run(self): while True: rlist,wlist,elist = select.select(self.socket_list,self.conn_list,[],0.005) # wlist中表示已經連接成功的req對象 for sk in wlist: # 發生變換的req對象 sk.sock.sendall(b'GET /s?wd=alex HTTP/1.0\r\nhost:www.baidu.com\r\n\r\n') self.conn_list.remove(sk) for sk in rlist: chunk_list = [] while True: try: chunk = sk.sock.recv(8096) if not chunk: break chunk_list.append(chunk) except BlockingIOError as e: break body = b''.join(chunk_list) # print(body.decode('utf-8')) sk.func(body) sk.sock.close() self.socket_list.remove(sk) if not self.socket_list: break def baidu_repsonse(body): print('百度下載結果:',body) def sogou_repsonse(body): print('搜狗下載結果:', body) def github_repsonse(body): print('GITHUB下載結果:', body) t1 = Nb() t1.add('www.baidu.com',baidu_repsonse) t1.add('www.sogou.com',sogou_repsonse) t1.add('www.github.com',oldboyedu_repsonse) t1.run()
python單線程解決並發