--- ---復元コンテンツ始まります
TCPプロトコルモジュールは同時サーバーを実装しsocketserver使用しないでください。
輸入ソケット からスレッドの輸入糸 S = socket.socket() s.bind((' 127.0.0.1 '、56984 )) (s.listen 5 ) デフserver_while(conn)を: ながら真: 試す: データ = conn.recv( 1024年) 、印刷(data.decode(' UTF-8 ' )) conn.send(data.upper()) を除くConnectionResetError Cのように: プリント(c)の ブレーク conn.close() の場合 __name__ == ' __main__ ' : しばらく:真 CONN、ADDR = s.accept() 、T =スレッド(対象= server_while、引数= (CONN)) t.start()
輸入ソケット クライアント = socket.socket() client.connect((' 127.0.0.1 '、56984 )) しばらく真: client.send(B ' sdjflaasdfad ' ) データ = client.recv(1024 ) 印刷(データ)
GILグローバルインタープリタロック
PS:pythonの通訳、最も一般的なの多くがありますがCPythonのインタプリタです
同時になるシリアル犠牲効率が同じプロセスで複数のスレッドを防止するために使用されるデータのセキュリティを確保するためながら(実行:GILは、ミューテックスの本質であり、同じプロセス内で複数のスレッドを同時実行が、平行で達成することができません)
することはできません尋ねたリー・パイソンマルチスレッド、マルチコア利点を使用するには役に立たないではないのですか?使用する必要はありません最後に、Pythonのマルチスレッドは、状況に依存し、マルチスレッドプロセスを使用して、より一般的には確かに便利です+
メモリ管理CPythonのインタプリタはスレッドセーフではありませんので、GILの存在があります
(オープンクローズとコードのリリースに対応したアプリケーションコード)メモリ管理とは何ですか
ガーベジコレクション
1.参照カウント:彼らは結合関係を持っていると何の変数名が存在しない場合は、メモリ内のデータは、それが自動的に回復されます
2.マーク・クリア:メモリをアプリケーションに充填されようとしているとき、それは自動的にトリガされます
3世代回復:異なるレベルに分類価値生存時間、周波数走査の高いガベージコレクション機構より低いレベルに依存
マルチコア利点の利点は役に立たないのではない取ることができないのpythonのマルチスレッド化を依頼し続けますか?
研究python的多线程是否有用需要分情况讨论
四个任务 计算密集型的
单核情况下
开线程更省资源 (单核的话 进程 和 线程 都可以并发 但是 线程 更省资源)
多核情况下 一次任务 10秒
开进程 10s (进程可以并行 同时运行4个 进程同时计算)
开线程 40s (需要计算4次的时间才能计算完)
四个任务 IO密集型的
单核情况下
开线程更节省资源(都要等 所有线程节省资源)
多核情况下
开线程更节省资源(即使进程可以并行 但是也需要等 而 线程 可以并发 相差不大 所以使用 线程节省资源)
from threading import Thread import time n = 100 def task(): global n tmp = n time.sleep(1) #相当释放了锁 release n = tmp -1 t_list = [] for i in range(100): t = Thread(target=task) t.start() t_list.append(t) for t in t_list: t.join() print(n)
死锁
RLock (from threading import Thread,Lock,RLock) 又叫递归锁
Rlock可以被第一个抢到锁的人连续的acquire和release
每acquire一次锁身上的计数加1
每release一次锁身上的计数减1
只要锁的计数不为0 其他人都不能抢
from threading import RLock,Thread mutex = RLock() class MyThread(Thread): def __init__(self, name): super().__init__() self.name = name def run(self): mutex.acquire() print('{}抢到了锁'.format(self.name)) mutex.acquire() print('{}抢到了锁'.format(self.name)) mutex.acquire() print('{}抢到了锁'.format(self.name)) mutex.acquire() print('{}抢到了锁'.format(self.name)) mutex.release() print('{}释放了锁'.format(self.name)) mutex.release() print('{}释放了锁'.format(self.name)) mutex.release() print('{}释放了锁'.format(self.name)) mutex.release() print('{}释放了锁'.format(self.name)) if __name__ == '__main__': for i in range(10): t = MyThread(i) t.start()
信号量 (信号量可能在不同的领域中 对应不同的知识点 例如Django)
互斥锁:一个厕所(一个坑位)
信号量:公共厕所(多个坑位)
from threading import Semaphore,Thread import time import random sm = Semaphore(5) # 造了一个含有五个的坑位的公共厕所 使用方法和 LOCK一样 生成对象 def task(name): sm.acquire() print('%s占了一个坑位'%name) time.sleep(random.randint(1,3)) sm.release() for i in range(40): t = Thread(target=task,args=(i,)) t.start()
抢到锁的人执行完后走了 马上就会有人来了
event事件
方法 : set wait Event
生成对象 e = Event
复习 queue模块
同一个进程下的多个线程本来就是数据共享 为什么还要用队列
因为队列是管道+锁 使用队列你就不需要自己手动操作锁的问题
因为锁操作的不好极容易产生死锁现象
q = queue.Queue() 方法 put get 取完原地等待
q = queue.LifoQueue() last in fast out 后进 先出
q = queue.PriorityQueue() put() 里面放的是元组 数字越小 优先级越高 例如 (-5, '哈哈哈')