我將同時寫入來自TCP/IP連接和共享內存隊列的程序處理請求。這意味着程序應該阻塞,直到隊列中有請求或者套接字上有輸入。然後它會處理請求並繼續。有沒有辦法在單線程中做到這一點?我的意思是某種select
同時使用信號量和套接字。對我而言,延遲很重要,我也不想忙於等待。該程序將在Windows上運行。謝謝。有沒有辦法阻塞單個線程,直到信號量或輸入事件?
回答
等待幾種可能的事情之一發生的Windows方式是WaitForMultipleObjectsEx
。你給它一個可以變成「信號」的Windows「句柄」數組(這些句柄稱爲同步對象),當它們中的任何一個被髮信號時,函數返回並告訴你它是哪一個。
問題是,在WinSock庫中實現的套接字不是Windows句柄。您無法將其放入WaitForMultipleObjectsEx
陣列中。
幸運的是,WinSock提供的函數WSAEventSelect
可以將套接字鏈接到Windows事件對象。事件對象是最簡單的同步對象類型。在這種情況下,當套接字準備好讀取時,您會要求它發出事件對象的信號(FD_READ
)。然後你可以將事件對象放入數組旁邊的信號量。
Windows Semaphore已經是一個同步對象 - 請參閱MSDN中的CreateSemaphore
。當它的計數大於0時就會發出信號。(這是你對信號量的期望)
如果你不理解同步對象的整體思想,並且閱讀MSDN沒有幫助,我會推薦Jim Beveridge的書多線程在Win32中的應用。這是一本舊書,所以它沒有套接字或信號量,但它解釋瞭如何使用事件對象,互斥體和一般的WaitForMultipleObjects
;那麼套接字和信號量將很容易理解。
是一種抽象出I/O事件的方法,它有手動觸發事件的方法。
建立基於文件的事件與libevents看起來像這樣(從文檔複製):
void callback_func(evutil_socket_t fd, short what, void *arg) { ... }
struct event *ev1, *ev2;
struct event_base *base = event_base_new();
/* The caller has already set up fd1, fd2 somehow, and make them
nonblocking. */
ev1 = event_new(base, fd1, EV_TIMEOUT|EV_READ|EV_PERSIST, callback_func,
(char*)"Reading event");
ev2 = event_new(base, fd2, EV_WRITE|EV_PERSIST, callback_func,
(char*)"Writing event");
event_add(ev1, NULL);
event_add(ev2, NULL);
如果你想創建不與任何文件描述符相關聯的事件,傳遞-1
這一翻譯的FD的:
ev = event_new(base, -1, EV_PERSIST | EV_READ, callback_func, NULL);
event_add(ev, NULL);
現在,而不是養信號,觸發事件:
event_active(ev, EV_WRITE, 0);
一種方法是使用重疊I/O並使用hEvent
機制來發送I/O完成信號。然後您可以使用WaitForMultipleObjects()
API等待隊列信號和hEvent
/s。
另一種方法是使用重疊的I/O和完成例程。然後,您可以在信號燈等待在循環與WaitForSingleObectEx()
API與bAlertable
參數設置爲true,使線可以處理排隊的完成例程,如:
while(WAIT_IO_COMPLETION!=WaitForSingleObjectEx(queueSema,INFINITE,true)){
[deque object and handle it];
};
這兩種方案都允許您設置超時輪詢服務器保持連接打開和/或檢查它是否關閉。
- 1. 有沒有辦法驗證沒有線程阻塞?
- 2. 非阻塞ConnectNamedPipe事件沒有得到信號
- 3. 多線程,阻塞和信號量
- 4. 沒有阻塞線程
- 5. 有沒有辦法在VBS中執行非阻塞IO或以某種方式向COM事件發出信號?
- 6. 如果沒有線程阻塞信號,並且一個線程在`sigwait()`中,是否有保證被阻塞的線程會接收下一個信號?
- 7. 阻塞,直到事件
- 8. 有沒有辦法將升壓信號直接連接到另一個信號?
- 9. 有沒有辦法阻止主線程,直到完成一個迴轉工作?
- 10. 查詢一個沒有阻塞的PHP信號量?
- 11. 阻塞輸出,直到輸入完成使用線程java
- 12. 信號量阻塞和解除阻塞
- 13. iPhone - 線程狀態信號沒有解除阻塞等待線程
- 14. .NET - 阻塞主線程,直到有任何可用線程
- 15. 優先獲取信號量阻塞線程的方法?
- 16. posix線程阻塞信號並解除阻塞
- 17. java stacktrace顯示阻塞的線程,但沒有關於阻塞它的信息
- 18. 更新GMSMarkers沒有阻塞主線程
- 19. 阻塞信號
- 20. 有沒有辦法阻止生成CR字符的直線?
- 21. 有沒有辦法在java中阻塞套接字和阻塞隊列?
- 22. Nacl_IO阻塞線程,直到fopen完成
- 23. 網絡阻塞到非阻塞,只有線程作爲選項?
- 24. 程序終止後,有沒有辦法保存輸入信息?
- 25. 阻塞,直到事件完成
- 26. 有沒有辦法假髮射信號?
- 27. 有沒有辦法列出Django信號?
- 28. Java輸入流「阻塞」和多線程
- 29. 沒有阻塞或線程的Android-dev AudioRecord
- 30. 有沒有什麼辦法來防止輸入事件jquery datepicker