2017-01-21 86 views
2

我的第一篇文章,很抱歉,如果不符合規則。 需要在C問題的建議。是否可以更改信號處理程序返回點?

我正在使用信號處理程序(SIGALRM)與用戶(Stdin)的輸入超時。 如果用戶沒有輸入任何內容,那麼:

  1. 超時過期

  2. 信號處理函數中調用

  3. (的問題) - >返回到同一線路發生超時之前。

重要: 我不能使用select和因爲它是一個第三方機制,我使用,必須使用他們的方法不能使用輪詢功能。 他們最終使用select,但它不是直接的,我只需要使用他們的方法。

問題是: 從信號處理程序返回後,我仍然'卡在'等待輸入的同一行 我不能使用longjmp,不能調用其他方法,不能打印消息到用戶不能使用goto 所有不安全的處理而產生錯誤

代碼看起來是這樣的:。

sa.sigaction(SIGALRM, &handler,Null): 
. 
. 
While(done! =1) 
{ 
    alarm(20); //20 seconds timeout started 
    If(ReadLineMethod()>0) //wait for successful input from stdin 
    { 
     If(inputErr ==1) 
     { 
      **here(for example) I want to print user that timeout  occured and return from the program (exit) ** 
      } 
    alarm(0); 
    done==1; 
    // Do stuff here 
    } 
} 



/* Rest of the program before exit */ 

的同時是要求特定的輸入,直到他的類型是正確的或超時將他踢出。

void handler (int signum) 
{ 
inputErr==1;// global parameter 
} 

是否有任何解決方法讓我跳過從處理程序返回後讀取輸入的那一行? 或者至少是管理打印一個正確的消息給用戶,超時發生?而不是隻是返回並再次卡住輸入再次大聲笑。

非常感謝。

+0

是的。你可以使用'setjmp()'和'longjmp()'的組合。 – DyZ

+0

爲什麼不打印並從處理函數本身退出?你可以這樣做,如果你退出程序。 – user1952500

+0

那麼,你可以通過'siginterrupt(SIGALRM,1)'中斷'read'調用,並在'EINTR'錯誤分支中測試取消標誌。然後'longjmp'也應該是信號安全的。如果'ReadLineMethod'不在你自己的控制之下,事情會變得棘手,在這種情況下,你可能需要一些痛苦的黑客,比如關閉標準輸入文件描述符。 – doynax

回答

0

使用處理程序引發的標誌。用這個標誌來調節打印。您需要用互斥鎖保護此標誌。

+0

放置空調的地方在哪裏? 由於處理程序返回到我堅持的If(ReadLineMethod()> 0)行。 – rozmanro

0

如果你不允許重新實現ReadLineMethod()更合理,那麼使用線程怎麼樣?我不是pthread的專家,但你可以設置一些事情,以便在一個線程上發生ReadLineMethod,並且在另一個線程上發生錯誤輪詢。甚至有似乎是一個pthread_cancel可以功能,可以強制停止讀取器線程如果需要的話:http://man7.org/linux/man-pages/man3/pthread_cancel.3.html

+1

我已經在這裏有很多線程,最好避免使用更多的線程。 謝謝。 – rozmanro

0

因爲你有這麼多的限制,一個方式來獲得在這個系統總量控制將是:

  1. 創建一個線程並在該線程中運行ReadLineMethod()
  2. 創建另一個線程並在該線程中使用一個計時器。不要使用信號,要麼檢測到隕石已經用完。
  3. 當定時器線程知道定時器已經運行我們的時候,讓它殺死(1)中的線程。
  4. 否則,如果ReadLineMethod()已經完全運行完畢,讓計時器線程什麼也不做並且完成。

當然,這是因爲要求而令人費解。如果知道基本要求,可能會有更好的選擇。

相關問題