开发者

C / pressing ctrl+c raises signal several time?

After pressing ctrl+c I get the following output. Regarding to the code, why does the line signal 2 was raised, exiting... appear several times even I pressed the keys only once?

My output looks like that:

-sh-2.05b# ./proxyp 192.168.1.100
shmget id: 65538
signal 10 was raised, should write out
signal 10 was raised, should write out
signal 2 was raised, exiting...
signal 2 was raised, exiting...
signal 2 was raised, exiting...
signal 2 was raised, exiting...
signal 2 was raised, exiting...

My source for the thread handling the sign开发者_如何学运维als looks like that (the program is not yet finished, so don't worry about the shared memory or anything else):

/* global variables */
wuint32 sh_id;

/* signal handlers */
void sgn_exit_programm(int sig, siginfo_t *siginfo, void *context);
void sgn_write_stdout(int sig, siginfo_t *siginfo, void *context);

/* main thread */
void *mgmtSrvcThread(port_configuration_data *p) {
struct sigaction sig_action_exit, sig_action_write;

shared_data sh_data = p->sh_mem;
sh_id = sh_data.shm_id;

wuint32 shm, shmid;

if((shmid = shmget(MEMKEY, MAXMYMEM, 0666)) < 0) {
    perror("shmget");
    exit(1);
}

if((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
    perror("shmat");
    exit(1);
}

/* Set up the structure to specify the new action */
sig_action_exit.sa_handler = sgn_exit_programm;
sig_action_write.sa_handler = sgn_write_stdout;
sigaction(SIGINT, &sig_action_exit, NULL);
sigaction(SIGUSR1, &sig_action_write, NULL);

while(1) {
    sleep(1);
}

return (void*)0;
}


void sgn_write_stdout(int sig, siginfo_t *siginfo, void *context) {
    printf("signal %d was raised, should write out\n", sig);
}


void sgn_exit_programm(int sig, siginfo_t *siginfo, void *context)
{
    printf("signal %d was raised, exiting...\n", sig);
    sleep(1);
    exit(0);
}

Maybe little bit more about it: I handle several threads within a master. One of the threads is just a management thread that shall handle the output to stdout and handles signals. The source is above. Inside the shared memory the message shall appear that the thread should write to stdout. That's it.

update after adding more code, it is sure that the handler is called more than once.

void sgn_exit_programm(int sig, siginfo_t *siginfo, void *context)
{
printf("signal %d was raised, exiting...\n", sig);
fflush(stdout);
if(shmdt(data) < 0) {
    perror("shmdt");
    exit(1);
} else {
    printf("detached successful\n");
}

sleep(1);
exit(0);
}

And that's the output for it, as you can see, the detaching task is done once successfully:

-sh-2.05b# ./proxyp 192.168.1.100
shmget id: 65538
signal 2 was raised, exiting...
detached successful
signal 2 was raised, exiting...
shmdt: Invalid argument
signal 2 was raised, exiting...
shmdt: Invalid argument
signal 2 was raised, exiting...
shmdt: Invalid argument
signal 2 was raised, exiting...
shmdt: Invalid argument

Thanks in advance.


Don't "do work" in your signal handler. Set a flag and handle it in your normal program flow. Working with signals and threads is also interesting business. My guess is that things are getting confused because more than one thread sees the signal and attempts to react to it. I believe the "main" thread is the only thread that is supposed to receive the signal, but it may be undefined (it's been a while, sorry).

This link may also be of use (first site on google search): http://uw714doc.sco.com/en/SDK_sysprog/PTL_ThdsSigs.html

If you set a bit somewhere (global variable or something else), you'll be able to at least handle the signal in the normal flow of the program and if the signal happens twice, it'll only set the bit true twice which is of no consequence.


May be the printf statement in SIGINT signal handler resides in stdout buffer, so when every threads is exiting, its printing that statement & then exiting.

Can you put fflush(stdout); statement after printf() statement & try it again.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜