标签:star oba 暂停 解释 ddr socket art 不同的 端口
要使用Python的多线程,首先要了解一个概念。GIL(global interpreter lock),翻译过来就是以解释器为单位的全局锁。
用过线程锁的都知道,LOCK就是用来管理住线程,让一个指定的线程先运行,其他的先暂停(等待),避免线程的混乱,尤其是在共用变量的情况下。
GIL也是一样的概念,但是不同的是:
1.你可以想成他是解释器控制的
2.线程的指定是随机的
3.每个线程acquire运行机会后,可运行的内容很少(因此线程间的切换超级快)
因此,多线程看起来好像是多个线程一起运行,实际上也是大家轮流。比起单线程,他还多了一个线程切换的开销,因此执行效率上,很多时候是不如单线程的。
那多线程有什么用的,我认为在以下及方面,还是用多线程比较有效率:
1.单线程只能根据顺序一行行从上往下执行。那你想一遍操作前台,一边后台记录日志的时候,就需要用到多线程。或者你想一边运行脚本,一边等待指令来停止脚步的时候,也需要多线程。
2.对于IO密集型的线程,多线程则可以提高效率。例如下面的例子,线程向服务器发送信息,服务器接收后等待5s再返回给线程。如果用单线程的方式,则一共要等待10s
from client import send_and_receive def main(): start_time = time.time() for i in [40080,40081]: t = Thread(target=send_and_receive, args=(i,)) t.start() t.join() end_time = time.time() print("Total time: {}".format(end_time - start_time)) if __name__ == ‘__main__‘: main()
而使用多线程的方式,则一共只要等待5左右s,因为这个等待是同步的
from client import send_and_receive def main(): start_time = time.time() for i in [40080,40081]: t = Thread(target=send_and_receive,args=(i,)) t.start() t.join() end_time = time.time() print("Total time: {}".format(end_time - start_time)) if __name__ == ‘__main__‘: main()
****************************client**********************
import socket def send_and_receive(port): s_obj=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s_obj.connect((‘localhost‘,port)) s_obj.send(‘x‘) while True: buf=s_obj.recv(1024) if buf!=‘‘: return buf
****************************server**********************
#为更准确的统计时间,服务器写了2个不同端口的,而不是在服务器中使用线程
import socket import time s_obj=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s_obj.bind((‘localhost‘,40080)) s_obj.listen(5) while True: conn,ipaddr=s_obj.accept() while True: if conn.recv(1024)!=‘‘: time.sleep(5) print ‘send back‘ conn.send(‘back‘) conn.close() break
标签:star oba 暂停 解释 ddr socket art 不同的 端口
原文地址:https://www.cnblogs.com/fishbiubiu/p/10202028.html