2017-05-21 38 views
0

我得到了這個問題,我將在下面簡化:çLinux的信號和功能

#include <stdio.h> 
#include <signal.h> 

int main(void) { 
    signal(SIGALRM, &INThandler); 

    //get menu options which Im not going to put here 
    game(...stuff...); 
} 

void game(..stuff...) { 
    //do the game stuff AND set an alarm() 
} 

void INThandler(int sig) { 
    system("clear"); 
    printf("Time is up!\n"); 
    //I WANT game() TO STOP WHICH WILL EXIT TO MAIN WHERE MORE STUFF IS HAPPENING 
} 

在遊戲中()我有

while(counter <= amount) 

所以我想通過變量計數器和金額成INThandler,所以我可以改變它們,所以條件是錯誤的,但只有當報警爲0並且不用參數調用時才調用INThandler。遊戲()繼續,我不希望它。如果有更好的方法,請告訴我。

+0

什麼問題?如何傳遞參數或被調用的函數只有一次? –

+0

請注意,您可以安全地從信號處理程序中僅調用異步信號安全函數。 [請參閱POSIX標準以獲取解釋和指定的函數列表](http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03)。 'system()'和'printf()'*不是異步信號安全的。此外,Linux不符合POSIX標準,因爲Linux上的fork()不是異步信號安全的,因此您必須使用posix_spawn()來完全安全,儘管對於單線程應用程序來說不太可能'fork()'的問題。 –

回答

1

使用全局變量計數器和金額?

0

當函數被調用並且該函數中包含變量時,這些變量將被分配到堆棧上。如果你定義了一個全局變量,它將會在程序加載時被分配。您的信號處理程序應該可以訪問這些變量。

#include <stdio.h> 
#include <signal.h> 
#include <stdlib.h> //Also include this, needed for exit(returncode) 

int counter; //Not inside any function 
int amount; //All functions may access these 

int main(void) { 
    signal(SIGALRM, &INThandler); 

    //get menu options which Im not going to put here 
    game(...stuff...); 
} 

void game(..stuff...) { 
    //do the game stuff AND set an alarm() 
} 

void INThandler(int sig) { 
    //Do stuff with counter and amount 
    //system("clear"); I recommend that you do not use system to clear the screen, system(command) is inefficient. 
    printf("\033[H\033[JTime is up!\n"); 
    //Do that extra stuff you want to do in main here, then 
    exit(0); 
} 

另注:根據在Linux編程手冊信號(2):

唯一便攜使用信號的()是一個信號的配置設定成 SIG_DFL或SIG_IGN。使用signal()建立信號處理程序時的語義在不同系統中是不同的(並且POSIX.1明確允許 這個變體);不要爲此使用它。

POSIX.1通過指定sigaction(2)解決了可移植性問題,當信號處理程序調用 時, 提供了對語義的顯式控制;使用該接口而不是signal()。

要使用的sigaction註冊信號處理程序,

#include <signal.h> 

int main(){ 
    const struct sigaction saSIGALRM = { 
     .sa_handler = mySignalHandler, //replace this with your signal handler, it takes the same parameters as using signal() 
    }; 
    sigaction(SIGALRM, &saSIGALRM, 0); 
} 

所以,很簡單比看起來。請記住,由於編程效率低下,今天計算機運行緩慢。請爲高效程序請用此代替。

Click here for more cool things sigaction can do, along with why not to use signal()