日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

浅谈python异步IO,同步IO,线程与进程~

發布時間:2025/3/15 python 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅谈python异步IO,同步IO,线程与进程~ 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

主線程下的線程之間是可以通信的,但是父進程下的子進程之間不能主動通信,但是子進程想要實現通信也是可以的,可以選擇折中的方法來實現,比如multiprocessing.Queue,用法與線程中的queue基本一致,直接上例子:

import threading from multiprocessing import Process,Queue import time def thre(qq):qq.put([1,'xixi',2])if __name__ =='__main__':q = Queue()p = Process(target=thre,args=(q,))#進程中,因為進程內存是獨立的,所以不能相互調用,必須傳入參數,這個q其實是復制了一份Queue的實例,如果和線程一樣不傳參數,就會報錯** not find。。。因為內存不共享。 #p =threading.Thread(target=thre) #線程中,不傳參數是可以調用函數thre,因為他們是在同一個內存地址下操作【上面改為def thre():】,當然傳參數也沒問題。 p.start()print(q.get())#進程之間想要有聯系,主動無法聯系,這是硬傷,就如qq和word一樣,但是如果非要他們有聯系,就是從word復制文字到qq里(或者qq復制圖片文字到word里面這樣),這樣貌似兩者有聯系,實際上只是克隆了那段文字的關系,但是看起來好像就有聯系了,那么python中process之間的通信就是可以考慮通過 Queue來實現,Queue內部操作其實就是通過pickle的功能來實現傳參數等各種聯系的 還有一個是pipe:通過管道來傳遞,也是建立一個pipe的實例化對象。 from multiprocessing import Process,Pipedef f(conn):conn.send('balabala')print(conn.recv())if __name__=='__main__':parent_conn,child_conn=Pipe()#實例化后是返回兩個值,一個是父接頭一個是子接頭,因為是管道。p = Process(target=f,args=(child_conn,))p.start()print(parent_conn.recv())parent_conn.send('babababa')

這樣也能實現數據的傳遞,但都不是共享

進程之間要實現共享,需要用manager。

from multiprocessing import Process,Manager import time,osdef thre(dd,ll):dd[os.getpid()] = os.getppid()ll.append(os.getpid())print(ll)print(dd)if __name__ =='__main__':manager = Manager()d = manager.dict()l = manager.list(range(3))t_list = []for i in range(10):p = Process(target=thre,args=(d,l))p.start()t_list.append(p)for res in t_list:res.join()#等待的意思

此時字典 d 和 列表 l,他們的數據同時都可以被進程修改覆蓋,只不過我這里用的是os.getpid()獲取的數據不一致,如果是一致的,那么最終字典只有一個k-v,列表是10個一樣的數據。

?

進程鎖的存在是為了輸出同一個屏幕不要亂。。。僅此而已

?

進程池的作用和線程中的信號量差不多,同一時間允許幾個進程同時運行


其中有 apply 和apply_async,一個是串行操作,一個是并行操作。

from multiprocessing import Pool import time,osdef thre(dd):time.sleep(1)print('the process:',os.getpid())return dd+100 def g(c):print('haha',c,os.getpid())#start_time = time.time() # l=[] if __name__ =='__main__':p_ = Pool(3)#允許同時運行的進程數為3。print(os.getpid())for i in range(10):p_.apply_async(func=thre,args=(i,),callback=g)#【callback是回調函數,傳的參數是thre的返回值】 p_.close()p_.join()#這里如果不加join,在并行中會直接close,程序會直接關閉,加了join,主進程就會等待子進程結束以后最后才關閉,這個只在并行中有用,串行中沒有什么作用。一定要先close再join

協程:可以實現高并發,本質上就是單線程,一個cpu支持上萬個協程并發
gevent(自動觸發) 和 greenlet(手動觸發)

import geventdef fun1():print('runing 1 ...')gevent.sleep(2)#模仿ioprint('running 2 ...')def fun2():print('running 3 ...')gevent.sleep(3)print('running 4')def fun3():print('running 5 ...')gevent.sleep(0)print('end?')gevent.joinall([gevent.spawn(fun1),gevent.spawn(fun2),gevent.spawn(fun3)])

運行結果:

runing 1 ...
running 3 ...
running 5 ...
end?
running 2 ...
running 4
----------------------
sleep相當于觸發的按鈕,出現一次sleep,就去找下一個函數中的內容打印等操作,sleep內的時間相當于他卡幾次,sleep(3)相當于卡3秒,如果其他已經沒卡著,就馬上執行沒卡著的語句,知道最后回來等到時間結束執行最后這個語句。協程用于多并發爬蟲中效果很好。

import gevent,time import urllib.request as ul from gevent import monkey monkey.patch_all()#這個標識代表把所有程序都當做io直接切換操作,不加這句話,因為gevent不會辨認出urllib的有io操作,相當于串行操作。 def f(url):print('GET %s'%url)res = ul.urlopen(url).read()print('recv bytes %s from %s'%(len(res),url))time_start = time.time() l=['https://www.python.org/','http://km.58.com/','http://kan.sogou.com/dongman/','http://news.sohu.com/'] for i in l:f(i) print('同步時間:',time.time()-time_start) async_time = time.time() gevent.joinall([gevent.spawn(f,'https://www.python.org/'),gevent.spawn(f,'http://km.58.com/'),gevent.spawn(f,'http://kan.sogou.com/dongman/'),gevent.spawn(f,'http://news.sohu.com/')]) print('異步時間:',time.time()-async_time)

運行結果:
GET https://www.python.org/
recv bytes 48860 from https://www.python.org/
GET http://km.58.com/
recv bytes 104670 from http://km.58.com/
GET http://kan.sogou.com/dongman/
recv bytes 12713 from http://kan.sogou.com/dongman/
GET http://news.sohu.com/
recv bytes 170935 from http://news.sohu.com/
同步時間: 3.780085563659668
GET https://www.python.org/
GET http://km.58.com/
GET http://kan.sogou.com/dongman/
GET http://news.sohu.com/
recv bytes 12690 from http://kan.sogou.com/dongman/
recv bytes 170935 from http://news.sohu.com/
recv bytes 104670 from http://km.58.com/
recv bytes 48860 from https://www.python.org/
異步時間: 2.5934762954711914

?

用戶空間和內核空間(kernel)
現在操作系統中都是采用虛擬存儲器,操作系統的核心是內核,獨立于普通的應用程序,可以訪問受保護的內存空間,也有訪問硬件設備的權限,為了保證用戶進程不能直接操作內核(kernel),保證內核的安全,操作系統把虛擬空間分為兩部分,一部分為內核空間,一部分為用戶空間。

進程切換
為了控制進程的執行,內核必須有能力掛起在CPU上運行的進程,并且恢復以前掛起的某個進程的執行,這種行為稱作進程切換,因此,任何進程都是在操作系統內核的支持下運行的,與內核緊密相連。
從一個進程的運行轉到另一個進程上運行,其實就是保存上下文就切換了。下次再來又從之前保存的位置開始。

進程的阻塞:
正式執行的進程,由于期待的某件事情并未發生,如請求系統資源失敗等待,等待某種操作的完成,新數據尚未達到或無新工作開始等,則有系統自動執行阻塞原語,使自己由原來的運行狀態轉為阻塞狀態暫停等待()
。可見,進程的阻塞是進程自身的一種主動行為,也因此只有處于運行狀態的進程(獲得CPU),才可能將其轉為阻塞狀態,當進程進入阻塞狀態時候,不耗費CPU資源的。

緩存I/O
又被成為標準IO,大多數文件系統默認I/O操作都是緩存I/O,在Linux的緩存I/O機制當中,操作系統會將I/O的數據緩存在文件系統的頁緩存中,也就是說,文件數據會被拷貝到系統內核的緩沖區中,然后再從系統內核的緩沖區拷貝到用戶的進程內存里也就是應用程序的地址空間。缺點就是數據會在用戶進程應用程序地址空間和內核空間反復拷貝操作,這時對于CPU和內存的開銷很大。


I/O模式
同步IO和異步IO:
同步IO中有:阻塞IO(blocking I/O),非阻塞IO(non-blocking I/O),多路復用IO(I/O multiplexing) 信號驅動(實際中不常用。在此暫時不記錄筆記)
異步I/O(asynchronous I/O)

阻塞IO:發起請求,然后等待數據準備(此時進程阻塞等待),直到數據準備好接受時,又到內核空間開始copy給用戶進程,此時又一次阻塞等待,直到數據全部發給用戶進程(客戶端)。

非阻塞IO:發起請求后,瘋狂發送驗證,數據未準備好時,并不會阻塞block,而是返回一個error給用戶進程,用戶進程會驗證是否error,是就繼續發出請求,來回驗證,(此時由于進程沒有阻塞,還可以干其他事,)不是就到了內核空間開始copy數據,此時其實還是阻塞,如果數據小會很快,數據大還是會感受到卡。最后用戶收到完整數據。

多路復用I/O:一次發起幾百次請求鏈接,無論哪條鏈接有數據回復,都會通知用戶進程開始接受數據,此時那幾條鏈接又開始進行內核copy直到進程收到完整數據(其實這里也是阻塞的)。這個模式的核心其實是用非阻塞IO的方式來驅動,所以形成多路復用,在用戶看來已經是多并發了。

異步I/O:這個就牛逼了,他發起請求,當場就收到回復‘去干你其他的事’,此時該進程開始其他部分運行,并未有任何阻塞,收到數據時,直接后臺開始內核copy,全部搞完以后直接‘送快遞到家門口’,給一個信號通知,用戶進程順手就接受了數據,此時整個進程根本沒有任何阻塞過程!這就是異步IO。

selectors
selectors中涵蓋了select,poll,epoll,詳細實例:

import selectors,socket sel = selectors.DefaultSelector()def accept(sock,mask):conn,addr = sock.accept()conn.setblocking(False)sel.register(conn,selectors.EVENT_READ,read)def read(conn,mask):data = conn.recv(1024).decode()if data:conn.send(('haha+%s'%data).encode())else:print('發什么?',conn)sel.unregister(conn)conn.close()sock = socket.socket() sock.bind(('localhost',5000)) sock.listen(1000) sel.register(sock,selectors.EVENT_READ,accept) while True:events= sel.select()for key,mask in events:callback = key.datacallback(key.fileobj,mask)
這個可以進行多并發運行。

好了 異步同步線程進程就到這了,人生苦短,我用python。

轉載于:https://www.cnblogs.com/Jason504327775/p/8503516.html

總結

以上是生活随笔為你收集整理的浅谈python异步IO,同步IO,线程与进程~的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 人妻精品一区 | 午夜精品久久久久久久久久久久久蜜桃 | 成人黄色在线看 | 亚洲一二三区视频 | 在线观看欧美成人 | 一级少妇女片 | 欧美日韩一区二区三区不卡 | 国产精品久久久久久妇女 | 亚洲精品免费在线观看视频 | 国产婷婷一区二区三区久久 | 色小姐av | 精品无码国产一区二区三区av | 不卡一区二区在线观看 | 日韩一区中文 | 天天在线免费视频 | 99国产精品99久久久久久粉嫩 | 成人黄色在线观看视频 | 精品国产乱码久久久久久1区2区 | 女人下边被添全过视频 | 中文字幕在线免费看线人 | 亚洲欧美一区二区三区四区五区 | 国产精品你懂的 | 亚洲97视频 | 中文在线一区 | 91视频最新入口 | 四虎影院永久地址 | 国偷自拍第113页 | 中文字幕日韩精品亚洲一区小树林 | 成年人黄色 | 午夜xxx| 婷婷激情五月网 | 亚洲1234区 | 午夜a级片| 思思在线视频 | 深夜精品视频 | 亚洲一区二区人妻 | 69网站在线观看 | 久久久999国产 | 最近最新最好看的2019 | 黄色av一级 | 精品国产一区二区三区无码 | 成人免费毛片男人用品 | 毛片视屏 | 最近高清中文在线字幕在线观看 | 青青草一区二区三区 | 婷婷色一区二区三区 | 伊人色网 | 亚洲成人生活片 | 一级特黄录像免费看 | 男女乱淫视频 | 一卡二卡三卡四卡 | 绯色av一区二区三区高清 | 欧洲性生活视频 | 日韩欧美理论 | 亚洲欧美一区二区三区孕妇 | 91久久极品少妇xxxxⅹ软件 | 激情伊人网 | 国产乱码在线 | 岛国精品在线播放 | 国产男女自拍 | 91成人入口 | 欧美无砖专区免费 | 欧美 日韩 国产一区 | 成人av一区二区三区在线观看 | 中文字幕观看av | 人人草人人爽 | 成人1区2区 | 久久亚洲中文字幕无码 | 解开乳罩喂领导吃奶 | 蝌蚪自拍网站 | 激情成人av | 欧美精品福利视频 | 深夜成人福利 | 96精品国产 | 在线免费观看亚洲视频 | 日本少妇全体裸体洗澡 | 91麻豆成人精品国产 | 奶罩不戴乳罩邻居hd播放 | 亚洲素人 | 66av欧美| 亚洲乱码一区二区三区 | 日日摸日日添日日躁av | 日批视频免费在线观看 | 大肉大捧一进一出视频 | av网站免费大全 | 亚洲福利影视 | 国产黄色片在线观看 | 在线免费看毛片 | 久久久久久久久久久久久国产 | 国产精品20p | 亚州欧美日韩 | 精品热| 性欧美free | 国产一级生活片 | 日韩一区二区三免费高清在线观看 | 香蕉影院在线 | 日本少妇xxxxx | 亚洲少妇一区二区 | 中文字幕在线观看一区二区 |