python 簡單搭建阻塞式單進程,多進程,多線程服務,python多線程
我們可以通過這樣子的方式去理解apache的工作原理
1 單進程TCP服務(堵塞式)
這是最原始的服務,也就是說只能處理個用戶端的串連,等當前用戶端關閉後,才能處理下個用戶端,是屬於阻塞式等待
from socket import *serSocket = socket(AF_INET, SOCK_STREAM)#重複使用綁定的資訊serSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR , 1)localAddr = ('', 7788)serSocket.bind(localAddr)serSocket.listen(5)while True: print('-----主進程,等待用戶端串連------') newSocket,destAddr = serSocket.accept() print('-----.主進程,接下來負責資料處理[%s]-----'%str(destAddr)) try: while True: recvData = newSocket.recv(1024) if len(recvData)>0: print('recv[%s]:%s'%(str(destAddr), recvData)) else: print('[%s]用戶端已經關閉...'%str(destAddr)) break finally: newSocket.close()
這種阻塞型自然不適合處理多用戶端的請求,於是有了改版
2 多進程服務
採取多進程處理多用戶端串連請求,對單進程進行了最佳化。
from socket import *from multiprocessing import *from time import sleep# 處理用戶端的請求並為其服務def dealWithClient(newSocket,destAddr): while True: recvData = newSocket.recv(1024) if len(recvData)>0: print('recv[%s]:%s'%(str(destAddr), recvData)) else: print('[%s]用戶端已經關閉'%str(destAddr)) break newSocket.close()def main(): serSocket = socket(AF_INET, SOCK_STREAM) serSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR , 1) localAddr = ('', 7788) serSocket.bind(localAddr) serSocket.listen(5) try: while True: print('-----主進程,,等待新用戶端的到來------') newSocket,destAddr = serSocket.accept() print('-----主進程,,接下來建立.個新的進程負責資料處理[%s]-----' client = Process(target=dealWithClient, args=(newSocket,destAddr)) client.start() #因為已經向.進程中copy了.份(引.),並且.進程中這個通訊端也沒有用處了 #所以關閉 newSocket.close() finally: #當為所有的用戶端服務完之後再進.關閉,表示不再接收新的用戶端的連結 serSocket.close() if __name__ == '__main__': main()
通過為每個用戶端建立一個進程的方式,能夠同時為多個用戶端進行服務;當用戶端不是特別多的時候,這種方式還行,如果有成百上千個,就不可取了,因為每次建立進程都消耗較多的資源,於是有了改進版
3 多線程服務
採用多執行緒多用戶端串連請求,由於線程共用資源,不用像進程那樣複製出多個資源,因此處理更快。
#coding=utf-8from socket import *from threading import Threadfrom time import sleep# 處理用戶端的請求並執行def dealWithClient(newSocket,destAddr): while True: recvData = newSocket.recv(1024) if len(recvData)>0: print('recv[%s]:%s'%(str(destAddr), recvData)) else: print('[%s]用戶端已經關閉'%str(destAddr)) break newSocket.close()def main(): serSocket = socket(AF_INET, SOCK_STREAM) serSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR , 1) localAddr = ('', 7788) serSocket.bind(localAddr) serSocket.listen(5) try: while True: print('-----主進程,,等待新用戶端的到來------') newSocket,destAddr = serSocket.accept() print('-----主進程,,接下來建立.個新的進程負責資料處理[%s]-----' client = Thread(target=dealWithClient, args=(newSocket,destAddr)) client.start() #這裡不要關閉,線程共用資源,關閉了會導致全部線程均關閉 #newSocket.close() finally: serSocket.close()if __name__ == '__main__':main()