目前我通libuv(windows) 的學(xué)習(xí)、調(diào)試了 fs,tcp,queue_work,async 四大模塊,發(fā)現(xiàn)如下:
1、libuv 的事件機制都時基于 IOCP 的,具體如下:
在初始化 uv_loop_t * loop時,如 loop = uv_default_loop();通過CreateIoCompletionPort 創(chuàng)建了IOCP handle。
在線程中調(diào)用uv_run 函數(shù)進行 GetQueuedCompletionStatus 查詢相關(guān)的各種請不完成情況,如UV_READ,UV_ACCEPT,UV_CONNECT 等TCP相關(guān)的操作請求。同時處理 文件讀寫、線程操作完成、ansync 請求都時能過PostQueuedCompletionStatus API 模擬 IO完成的,產(chǎn)生UV_WAKEUP 請求。
通過以上可以得知,所以IO操作,文件操作,線程池調(diào)度 都是統(tǒng)一用 IOCP的機制進行的。
2、fs 模塊中,讀寫文件一塊并沒有將文件handle 掛接到IOCP handle中,而是通過建立線程池,將所以文件操作通過線程池中線程同步操作的,線程完成后,通過PostQueuedCompletionStatus API 模擬 IO完成,產(chǎn)生UV_WAKEUP 請求完成。最終通過 uv_run 來調(diào)度的。
3、tcp 模塊,所有socket 都是 調(diào)用CreateIoCompletionPort 完成與IOCP的掛接,通過windows 的異步API 投送操作請求,如WSARecv。注意創(chuàng)建IOCP時,CreateIoCompletionPort 的NumberOfConcurrentThreads 值為1,標(biāo)明IOCP中,只有一個 活動線程進行監(jiān)聽。libuv中并沒有創(chuàng)建線程池來GetQueuedCompletionStatus ,需求調(diào)用 uv_run 進行監(jiān)聽。可以自己產(chǎn)生多線程進行調(diào)用 uv_run 進行高并發(fā)監(jiān)聽。
4、queue_work 線程池(fs 中也是用了類似的線程池),在調(diào)用 uv_queue_work 時,產(chǎn)生4個線程,并將用戶線程函數(shù)提交給空閑線程處理,線程處理完成后,通過PostQueuedCompletionStatus API 模擬 IO完成,產(chǎn)生UV_WAKEUP 請求完成。由于un_run 完成調(diào)度。
5、async 線程間通信機制,通過 uv_async_init 初始一個 async 對象并于IOCP掛接,產(chǎn)生一個UV_WAKEUP請求。在別外的線程中通過 uv_async_send(&async),通過PostQueuedCompletionStatus API 模擬 IO完成,在接收線程由un_run 完成調(diào)度。
其他待后續(xù)。。。。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請
點擊舉報。