10 線程 協程 socketserver 基於udp的socketserver
阿新 • • 發佈:2017-07-08
upper 復用 use style 結構 dto 阻塞 mil 等待 並發:偽並行,單核+多道
並行:只有多核才能實現真正的並行
同步:打電話,一個進程在執行某個任務時,另外一個進程必須等待其執行完畢,才能繼續執行
異步:發短信,一個進程在執行某個任務時,另外一個進程無需等待其執行完畢,就可以繼續執行,當有消息返回時,系統會通知後者進行處理,這樣可以提高執行效率
進程的創建:
1. 系統初始化
2. 與用戶交互
3. 在執行一個進程的過程中調用(Popen,os.fork)
4.批處理任務
系統的調用:
linux:fork
win:CreateProcess
linux的下的進程與windows下的區別:
1:linux的進程有父子關系,是一種樹形結構,windows沒有這種關系
2:linux創建新的進程需要copy父進程的地址空間,win下從最開始創建進程,兩個進程之間就是不一樣
線程:一條流水線的執行過程是一個線程,一條流水線必須屬於一個車間,一個車間的運行過程就是一個進程
(一個進程內至少一個線程)
進程是資源單位
而線程才是cpu上的執行單位
多線程:一個車間內有多條流水線,多個流水線共享該車間的資源(多線程共享一個進程的資源)
線程創建的開銷要遠遠小於進程
線程進程
操作系統的作用:
1.把硬件醜陋復雜的接口隱藏起來,為應用程序提供良好接口
2.管理,調用進程,並且把進程之間對硬件的競爭變得有序化
多道技術:
1.產生背景:為了實現單cpu下的並發效果
2.分為兩部分:
1:空間上的復用(必須實現硬件層面的隔離)
2:時間上的復用(復用cpu的時間片)
什麽切換?
1:正在執行的任務遇到的阻塞
2:正在執行的任務運行時間過長
進程:正在運行的一個過程/一個任務,由操作系統負責調用,然後由cpu負責執行
程序:就是程序員寫的代碼
並行:只有多核才能實現真正的並行
同步:打電話,一個進程在執行某個任務時,另外一個進程必須等待其執行完畢,才能繼續執行
異步:發短信,一個進程在執行某個任務時,另外一個進程無需等待其執行完畢,就可以繼續執行,當有消息返回時,系統會通知後者進行處理,這樣可以提高執行效率
進程的創建:
1. 系統初始化
2. 與用戶交互
3. 在執行一個進程的過程中調用(Popen,os.fork)
4.批處理任務
系統的調用:
linux:fork
win:CreateProcess
linux的下的進程與windows下的區別:
1:linux的進程有父子關系,是一種樹形結構,windows沒有這種關系
線程:一條流水線的執行過程是一個線程,一條流水線必須屬於一個車間,一個車間的運行過程就是一個進程
(一個進程內至少一個線程)
進程是資源單位
而線程才是cpu上的執行單位
多線程:一個車間內有多條流水線,多個流水線共享該車間的資源(多線程共享一個進程的資源)
線程創建的開銷要遠遠小於進程
為何要創建多線程?
1. 共享資源
2. 創建開銷小
多線程模擬文件編輯器
#!/usr/bin/python # -*- coding:utf-8 -*- from多線程模擬文件編輯器threading import Thread msg_l=[] format_l=[] def talk(): while True: msg=input(‘>>: ‘).strip() if not msg:continue msg_l.append(msg) def format(): while True: if msg_l: res=msg_l.pop() res=res.upper() format_l.append(res) def save(): while True: if format_l: res=format_l.pop() with open(‘db.txt‘,‘a‘,encoding=‘utf-8‘) as f: f.write(‘%s\n‘ %res) if __name__ == ‘__main__‘: t1=Thread(target=talk) t2=Thread(target=format) t3=Thread(target=save) t1.start() t2.start() t3.start()
線程對象的其他方法
#!/usr/bin/python # -*- coding:utf-8 -*- n=11111111111111111111111111111111111 import time from threading import Thread import threading def work(): time.sleep(2) print(‘%s say hello‘ %(threading.current_thread().getName())) if __name__ == ‘__main__‘: t=Thread(target=work) # t.setDaemon(True) t.start() t.join() print(threading.enumerate()) #當前活躍的線程對象,是一個列表形式 print(threading.active_count()) #當前活躍的線程數目 print(‘主線程‘,threading.current_thread().getName())線程對象的其他方法
單線程實現並發爬取網頁
#!/usr/bin/python # -*- coding:utf-8 -*- import requests import time # response=requests.get(‘https://www.python.org‘) # print(response.status_code) # print(response.text) def get_page(url): print(‘GET page:%s‘ %url) response=requests.get(url) if response.status_code == 200: print(response.text) start_time=time.time() get_page(‘https://www.python.org‘) get_page(‘https://www.yahoo.com‘) get_page(‘https://www.github.com‘) stop_time=time.time() print(‘run time is :%s‘ %(stop_time-start_time)) #11.989685773849487 from gevent import monkey;monkey.patch_all() import requests import time import gevent def get_page(url): print(‘GET page:%s‘ %url) response=requests.get(url) if response.status_code == 200: print(response.text) start_time=time.time() g1=gevent.spawn(get_page,url=‘https://www.python.org‘) g2=gevent.spawn(get_page,url=‘https://www.yahoo.com‘) g3=gevent.spawn(get_page,url=‘https://www.github.com‘) gevent.joinall([g1,g2,g3]) stop_time=time.time() print(‘run time is :%s‘ %(stop_time-start_time)) #8.745500326156616單線程實現並發爬取網頁
單線程實現並發的socket服務端
#!/usr/bin/python # -*- coding:utf-8 -*- from gevent import monkey;monkey.patch_all() from socket import * import gevent def server(ip,port): s = socket(AF_INET, SOCK_STREAM) s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) s.bind((ip,port)) s.listen(5) while True: conn, addr = s.accept() print(‘client‘,addr) gevent.spawn(talk,conn,addr) def talk(conn,addr): #通信 try: while True: res=conn.recv(1024) if not res:break print(‘client %s:%s msg:%s‘ %(addr[0],addr[1],res)) conn.send(res.upper()) except Exception: pass finally: conn.close() if __name__ == ‘__main__‘: server(‘127.0.0.1‘, 8080)單線程實現並發的socket服務端
#!/usr/bin/python # -*- coding:utf-8 -*- from socket import * c=socket(AF_INET,SOCK_STREAM) c.connect((‘127.0.0.1‘,8080)) while True: msg=input(‘>>: ‘).strip() if not msg:continue c.send(msg.encode(‘utf-8‘)) res=c.recv(1024) print(res.decode(‘utf-8‘))客戶端
socketserver實現並發
#!/usr/bin/python # -*- coding:utf-8 -*- import socketserver #MyHandler(conn, client_address, s) class MyHandler(socketserver.BaseRequestHandler): #通訊循環 def handle(self): while True: res=self.request.recv(1024) print(‘client %s msg:%s‘ %(self.client_address,res)) self.request.send(res.upper()) if __name__ == ‘__main__‘: s=socketserver.ThreadingTCPServer((‘127.0.0.1‘,8080),MyHandler) s.serve_forever() #鏈接循環socketserver實現並發
協程
import time def consumer(item): # print(item) x=111111 y=22222222222 z=3333333 a=‘abasdfasdfasdfasdfasdf‘ b=‘123213asdfasdfsadfasdf‘ pass def producer(target,seq): for item in seq: target(item) start_time=time.time() producer(consumer,range(100000000)) stop_time=time.time() print(‘run time is %s‘ %(stop_time-start_time)) import time def consumer(): # print(item) x=111111 y=22222222222 z=3333333 a=‘abasdfasdfasdfasdfasdf‘ b=‘123213asdfasdfsadfasdf‘ while True: item=yield def producer(target,seq): for item in seq: target.send(item) g=consumer() next(g) start_time=time.time() producer(g,range(100000000)) stop_time=time.time() print(‘run time is %s‘ %(stop_time-start_time))協程
#!/usr/bin/python # -*- coding:utf-8 -*- from gevent import monkey;monkey.patch_all() import gevent import time def eat(name): print(‘%s eat food first‘ %name) # gevent.sleep(5) time.sleep(5) print(‘%s eat food second‘ % name) def play(name): print(‘%s play phone 1‘ %name) # gevent.sleep(6) time.sleep(6) print(‘%s play phone 2‘ %name) g1=gevent.spawn(eat,‘egon‘) g2=gevent.spawn(play,name=‘egon‘) g1.join() g2.join() print(‘主‘)協程gevent(遇到IO自動切換)
基於udp的socket
#!/usr/bin/python # -*- coding:utf-8 -*- import socketserver class MyUDPhandler(socketserver.BaseRequestHandler): def handle(self): client_msg,s=self.request s.sendto(client_msg.upper(),self.client_address) if __name__ == ‘__main__‘: s=socketserver.ThreadingUDPServer((‘127.0.0.1‘,8080),MyUDPhandler) s.serve_forever()多線的udp服務端
#!/usr/bin/python # -*- coding:utf-8 -*- from socket import * s=socket(AF_INET,SOCK_DGRAM) s.bind((‘127.0.0.1‘,8080)) while True: client_msg,client_addr=s.recvfrom(1024) print(client_msg) s.sendto(client_msg.upper(),client_addr)服務端
#!/usr/bin/python # -*- coding:utf-8 -*- from socket import * c=socket(AF_INET,SOCK_DGRAM) while True: msg=input(‘>>: ‘).strip() c.sendto(msg.encode(‘utf-8‘),(‘127.0.0.1‘,8080)) server_msg,server_addr=c.recvfrom(1024) print(‘from server:%s msg:%s‘ %(server_addr,server_msg))客戶端
10 線程 協程 socketserver 基於udp的socketserver