原理邏輯:
將線程運行邏輯寫成非阻塞模式,以循環方式運行,通過event事件結束循環,線程就停止了。
在線程內部或線程父進程都可以控制線程停止。
代碼設計:
- 線程:使用原生threading.Thread重寫run函數
- 停止:使用threading.Event事件監聽觸發線程停止(multiprocessing.Event對Process同樣有同樣的效果)
- 使用線程建立socket服務端和客戶端,設置客戶端socket監聽超時事件
- 直接使用python內置的socket和threading,模擬soket通信和線程的啟停,此代碼在windos、linux、mac環境都可以直接運行
直接貼代碼:
1 # coding: utf-8 2 # author: elephanyu 3 import sys 4 import time 5 import socket 6 import traceback 7 from threading import Thread, Event 8 9 def now(): 10 now = time.time() 11 return '%s.%s' % (time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(now)), int(now % 1 * 1000)) 12 13 # socket server 14 class myserver(Thread): 15 def __init__(self, host='127.0.0.1', port=5000, time=1): 16 Thread.__init__(self) 17 self.host = host 18 self.port = port 19 self.time = time 20 sock = self.get_sock() 21 if sock: 22 self.sock = sock 23 else: 24 print 'Server get sock err an dieded!' 25 sys.exit(-1) 26 self.exit = Event() 27 print '%s Server init' % now() 28 29 def stop(self): 30 self.exit.set() 31 32 def get_sock(self): 33 try: 34 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 35 sock.settimeout(2) 36 sock.bind((self.host, self.port)) 37 sock.listen(5) 38 return sock 39 except Exception: 40 print traceback.format_exc() 41 return None 42 43 def run(self): 44 while not self.exit.is_set(): 45 try: 46 con, addr = self.sock.accept() 47 if con: 48 con.send('Hello, i am server!') 49 time.sleep(self.time) 50 recv = con.recv(1024) 51 if recv: 52 print now() + ' ' + addr[0] + ' server accept: ' + str(recv) 53 except Exception: 54 print traceback.format_exc() 55 print '%s Server nomal down!' % now() 56 57 # socket client 58 class myclient(Thread): 59 def __init__(self, host='127.0.0.1', port=5000): 60 Thread.__init__(self) 61 self.host = host 62 self.port = port 63 self.exit = Event() 64 print '%s Client init' % now() 65 66 def stop(self): 67 self.exit.set() 68 69 def run(self): 70 while not self.exit.is_set(): 71 try: 72 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 73 sock.settimeout(2) 74 sock.connect((self.host, self.port)) 75 sock.send('How are you, server?') 76 recv = sock.recv(1024) 77 if recv: 78 print now() + ' client accept: ' + str(recv) 79 sock.close() 80 except Exception: 81 print now() + ' ' + traceback.format_exc() 82 print '%s Client normal down!' % now() 83 84 if __name__ == '__main__': 85 host = '127.0.0.1' 86 port = 5000 87 speed = 1 88 rtime = 3 89 server = myserver(host=host, port=port, time=speed) 90 client = myclient(host=host, port=port) 91 server.start() 92 client.start() 93 time.sleep(rtime) 94 client.stop() 95 server.stop() 96 while True: 97 time.sleep(0.5) 98 s_status = server.is_alive() 99 c_status = client.is_alive() 100 print '%s Check server status: %s' % (now(), s_status) 101 print '%s Check client status: %s' % (now(), c_status) 102 if not s_status and not c_status: 103 break
代碼執行結果:
1 2018-04-20 11:04:20.292 Server init 2 2018-04-20 11:04:20.292 Client init 3 2018-04-20 11:04:20.293 client accept: Hello, i am server! 4 2018-04-20 11:04:21.295 127.0.0.1 server accept: How are you, server? 5 2018-04-20 11:04:21.295 client accept: Hello, i am server! 6 2018-04-20 11:04:22.296 127.0.0.1 server accept: How are you, server? 7 2018-04-20 11:04:22.296 client accept: Hello, i am server! 8 2018-04-20 11:04:23.298 127.0.0.1 server accept: How are you, server? 9 2018-04-20 11:04:23.298 Server nomal down! 10 2018-04-20 11:04:23.795 Check server status: False 11 2018-04-20 11:04:23.795 Check client status: True 12 2018-04-20 11:04:24.295 Check server status: False 13 2018-04-20 11:04:24.295 Check client status: True 14 2018-04-20 11:04:24.298 Traceback (most recent call last): 15 File "E:/project/DataIn/TestCode/test/socktest.py", line 76, in run 16 recv = sock.recv(1024) 17 timeout: timed out 18 19 2018-04-20 11:04:24.298 Client normal down! 20 2018-04-20 11:04:24.795 Check server status: False 21 2018-04-20 11:04:24.795 Check client status: False