2011-11-27 134 views
2

我們正在創建一個點對點程序(在c中),並且我們正在使用多線程,以便程序可以偵聽新連接以及接收/發送數據。多線程程序:等待輸入

問題是,我記得我的經理告訴我們,如果你有多個線程在同一個進程上運行,如果必須等待用戶輸入,整個進程將被「暫停」,所以其他線程都不會保留運行。

但是,我們一直在閱讀了,它好像如果一個線程是在輸入等待,其他都保持照常運行...

哪一個是正確的?如果我們有一個程序在一個線程上等待用戶輸入(你知道,比如連接到X或發送X消息),另一個線程正在無限循環中等待對方嘗試連接,它仍然會正在傾聽連接?

謝謝!希望這是有道理的......線程是如此混亂:(

回答

5

是的,在大多數當代操作系統中,一個進程內的多個線程可以等待輸入(從stdin,從套接字等),而其他可以當您等待頁面加載時(即,瀏覽器的某個線程正在等待來自連接到遠程主機的套接字的輸入)時,用戶界面不會凍結,而您在瀏覽互聯網時並不會凍結該頁面。

(...)和另一個線程只是坐在那裏在一個無限循環等待對等體嘗試連接(..) )

這就是所謂的忙等待它被認爲是一種不好的做法。看看select(2),epoll(4)或相關機制。

4

的問題是,我記得我的教授告訴我們,如果你有 在同一個進程中運行,如果一個人有等待 用戶輸入的多個線程,整個過程是「暫停」,所以沒有的其他 線程將繼續運行。

要麼你記得錯了,要麼你的教授還沒有真正嘗試過。

等待輸入的線程被阻塞。其他線程繼續運行良好。

...只是在無限循環坐在那裏等待同伴試圖 連接...

沒有! 請注意不要在多線程代碼中使用輪詢循環!你的線程'等待對等連接'更有可能等待Seamphore或Event發送信號。沒有涉及輪詢 - 直到信號燈發出信號才能運行。

2

如果一個線程被掛起,其他線程繼續執行(這是線程的主要原因!)。

但是,你不應該在一個線程中執行一個無限循環 - 這浪費了太多的處理器能力。相反,使用阻止功能。阻塞函數是一個函數,只要它可以做它應該做的事情或發生錯誤,它就會立即返回。雖然這樣的阻塞函數等待它所做的任何事情,但它不消耗任何處理器時間。

3

你很可能需要了解複用功能,如poll(或selectpselectppoll),它能夠等待輸入。當然,如果一個線程正在等待I/O,那麼其他線程可以很好地運行(除非互斥或其他東西阻塞了它們,例如參見pthread_mutex_lock)。

這在Linux上至少是真的,其中線程是內核實體(內核調度程序處理任務,即線程)。請參閱特定於Linux的clone系統調用 - 由線程庫使用。

3

在Unix/Linux中,您還可以使用系統調用select()處理多個文件描述符(如套接字,管道......)的I/O。

0

我看過這個答案,並且一直在尋找相同的東西。 因此,對於任何人來到這篇文章,我發現this examples顯示如何syncro用戶輸入和閱讀與線程。

不知道這是怎麼接近OP是在說什麼,但至少爲我工作。 我嘗試了syncro userinput以避免阻塞程序的其餘部分,但這有點不完全理解線程的力量。只要看看上面的鏈接,並運行示例3如果你不太熟悉線程。

因此,希望這對未來的任何人都有效:)