2011-10-18 28 views
0

在我編寫的程序中,我有一個主線程,它包含一個用於接受控制檯輸入的循環。但是,在某個時候會創建一個新的線程,該線程也會嘗試從stdin讀取。有一個變量表示這個其他線程已經啓動,但是fgets仍然在等待主線程中的輸入,所以在新線程啓動後輸入的第一個控制檯輸入被主線程而不是新線程錯誤地讀取。我怎樣纔能有一個新的線程「接管」標準輸入?

有沒有辦法解決這個問題?

有一件事我已經試過是(在主線程):

while(foo) { 
    if(busy) continue; 
    fgets(input,200,stdin); 
    if(busy) { 
     fputs(input,stdin); 
    } else { 
     // do whatever was supposed to be done with input intended for main thread 
    } 
} 

但我似乎因爲其他與fgets調用不讀通過的fputs寫入的數據流是如何工作的一種誤解。

+2

你爲什麼要這麼做?你確定沒有更好的設計將所有的I/O保持在同一個線程上嗎? –

+0

這將是理想的。我想我在看樹林的時候遇到了麻煩。 我會嘗試。 – Tiki

回答

1

創建一個布爾變量保護適當的同步原語。將其初始化爲false。當一個線程需要詢問用戶一個問題並得到答案時,等待變量變爲'假'(適合於您選擇的同步原語),然後將其設置爲true。做所有的輸出並獲得你需要的所有輸入。然後將該變量設置爲'false'並取消阻塞任何正在等待的線程(適用於您選擇的同步原語)。

對於pthreads,互斥和條件變量可能是最好的。對於Windows,關鍵部分和自動重置事件可能是最好的。

你的問題確實缺乏一些可能暗示不同答案的細節。當用戶不能確定兩個單獨的代碼路徑中的哪一個會得到他輸入的輸入時,用戶應該如何與程序進行交互?如果他鍵入一些內容然後點擊「輸入」,那麼代碼路徑看起來取決於他是否在另一個線程準備好之前點擊「輸入」,這看起來會造成不可用的程序。在幾乎所有的實際情況下,您都需要提示用戶,然後等待響應,然後一起釋放輸入和輸出。

+0

感謝您的輸入!這在某些時候肯定會有用,但對於這個程序,我已經重構了只有一個線程正在處理stdin。 – Tiki

+0

這是一個很好的解決方案。 –

0

爲了後代,這裏是我如何解決這個問題。

現在我只有一個線程等待輸入,並將該輸入的處理委託給特定於程序狀態的函數,而不是等待控制檯輸入。上述

的片段變成:

while(foo) { 
    fgets(input,200,stdin); 
    if(busy) { 
     busyStuff(input); 
    } else { 
     nonBusyStuff(input); 
    } 
} 

,並創建過一個具有與fgets調用沒有其他並行線程。