[英]branching vs multi-threading
代碼中有一條快速路徑,如下所示:
while(1){
select(fd_set...);
if (fd_isUserspace) {
process_user_packet(fd); // RPC involved
} else { // kernel
process_kernel_packet(fd); // RPC invovled
}
} // while(1)
基本上從一組fds中讀取一個活動的fd並對其進行處理。 當前,它是在if-else分支中完成的,僅在處理完成時返回。 我認為我可以通過在if-else中使用線程池(poolSize> = 2)來改善此情況,以便處理func立即返回,並可以為以后的fds重新開始while循環。
大概process _ * _ packet要做一些RPC工作以進行處理。
我知道將處理作業分派到一個線程可能會有一些開銷(thread_cond_signal / locking等),但是感覺由於process _ * _ packet可能花費較大的時間(由於RPC),也許值得。
想得到一些想法(也許是更好的主意),我認為這可能是一個關於如何設計才能獲得更好性能的非常普遍的問題。
-謝謝
我最近用Java寫了一個線程池(這是我的並行計算類所必需的,我知道它是內置的),如果編寫得當,它實際上非常快。
如果您使用多個線程,那么這里的一大優勢是:您不再有阻塞請求。 因為您可以同時處理多個請求,所以您將獲得更好的響應時間。
如果一個人花費相當長的時間來處理,發送或接收,則您不需要該數據包就一定會阻塞您的電子管。
使用一些線程池,您只需執行以下操作:
while(1){
select(fd_set...);
if (fd_isUserspace) {
submit_job(process_user_packet, fd);
} else { // kernel
submit_job(process_kernel_packet, fd);
}
} // while(1)
我們假設Submit_job具有簽名
void submit_job(void (*func)(void *), void *args);
這樣,線程池中的每個線程都可以簡單地獲取需要處理的函數和參數,然后調用func(args);。
我完全不用擔心派遣工作的成本。 如果處理花費的時間超過1毫秒(在真正好的實現中可能甚至更少),那么您將大放異彩。
只是一個想法,但是如果您丟掉select
並且每個文件描述符僅使用一個線程,該怎么辦? 唯一的主要缺點是,如果一次出現太多請求,則上下文切換開銷會增加,但是總之,它比等待時間更好。 優點是在非重載情況下上下文切換較少:內核在解除阻塞后立即直接喚醒線程以等待文件描述符,而不是先喚醒選擇線程,后者必須先喚醒線程才能處理請求。 當然,簡單性本身就是一種優勢……
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.