简体   繁体   中英

C linux signals and functions

I got this issue, which I will simplify below:

#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
}

In game() I have

while(counter <= amount)

So I wanted to pass the variables counter and amount into INThandler so I could change them so the condition is false, however INThandler is only called when the alarm is at 0 and is not called with parameters. game() continues and I don't want it to. If there is a better way please tell me.

使用全局变量作为计数器和数量?

When a function is called and that function has variables in it, those variables are allocated on the stack. If you define a global variable, it will be instead be allocated as the program loads. Your signal handler should have access to those variables.

#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);
}

Another note: according to signal(2) in the Linux programming manual:

The only portable use of signal() is to set a signal's disposition to SIG_DFL or SIG_IGN. The semantics when using signal() to establish a signal handler vary across systems (and POSIX.1 explicitly permits this variation); do not use it for this purpose.

POSIX.1 solved the portability mess by specifying sigaction(2), which provides explicit control of the semantics when a signal handler is invoked; use that interface instead of signal().

To register a signal handler using 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);
}

It's simpler than it looks. Remember, computers are slow today because of inefficient programming. Please, please, please, for efficient programs, use this instead.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM