gpt4 book ai didi

c - 关于sigsetjmp的一些错误

转载 作者:太空宇宙 更新时间:2023-11-04 11:34:44 26 4
gpt4 key购买 nike

我正在阅读 APUE,第 10 章。这是我的代码。

#include "apue.h"
#include <unistd.h>
#include <setjmp.h>
#include <time.h>
#include <errno.h>

static void sig_usr1(int), sig_alrm(int);
static sigjmp_buf jmpbuf;
static volatile sig_atomic_t canjmp;

int
main(void)
{
if(signal(SIGUSR1, sig_usr1) == SIG_ERR)
err_sys("signal(SIGUSR1) error");
if(signal(SIGALRM, sig_alrm) == SIG_ERR)
err_sys("signal(SIGALRM) error");
//print signal.
pr_mask("Starting main: ");
if(sigsetjmp(jmpbuf, 1)) {
pr_mask("End main: ");
exit(0);
}
canjmp = 1;
for(;;)
pause();
}

static void
sig_usr1(int signo)
{
time_t starttime;

if(canjmp == 0) {
return;
}

pr_mask("starting sig_usr1: ");
alarm(3);
starttime = time(NULL);
for(;;)
if(time(NULL) > starttime + 5)
break;
pr_mask("finishing sig_usr1: ");
canjmp = 0;
siglongjmp(jmpbuf, 1);
}

static void
sig_alrm(int signo)
{
pr_mask("in sig_arlm: ");
}

void
pr_mask(const char *str)
{
sigset_t sigset;
int errno_save;

errno_save = errno; /* we can be called by signal handlers */
if (sigprocmask(0, NULL, &sigset) < 0)
err_sys("sigprocmask error");

printf("%s", str);
if (sigismember(&sigset, SIGUSR1)) printf("SIGUSR1 ");
if (sigismember(&sigset, SIGALRM)) printf("SIGALRM ");
/* remaining signals can go here */

printf("\n");
errno = errno_save;
}

我以为输出会是这样的:

Starting main:
starting sig_usr1: SIGUSR1
in sig_alrm: SIGUSR1 SIGALRM
finishing sig_usr1: SIGUSR1
End main:

但似乎有些不对劲,实际上这是我的输出:

Starting main:
starting sig_usr1:
in sig_alrm:
finishing sig_usr1:
End main:

那是没有信号。请帮助我。

最佳答案

我认为问题可能出在您使用 signal() 而不是 sigaction() 来设置信号处理。并且 signal() 不会屏蔽任何其他信号 - 因此没有信号显示为被阻止。我修改了您的代码,如下所示,根据是否有任何参数使用 signal()sigaction()

#include <signal.h>
#include <unistd.h>
#include <setjmp.h>
#include <time.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

typedef void (*Handler)(int);
static void sig_usr1(int), sig_alrm(int);
static sigjmp_buf jmpbuf;
static volatile sig_atomic_t canjmp;
static void pr_mask(const char *str);

static void err_sys(const char *str)
{
int errnum = errno;
fprintf(stderr, "%s (%d: %s)\n", str, errnum, strerror(errnum));
exit(1);
}

static void set_sigaction(int signum, Handler handler)
{
struct sigaction nact;
nact.sa_handler = handler;
sigfillset(&nact.sa_mask);
//sigemptyset(&nact.sa_mask);
nact.sa_flags = 0;
if (sigaction(signum, &nact, 0) != 0)
err_sys("Failed to set signal handling");
}

int
main(int argc, char **argv)
{
printf("PID = %u\n", (unsigned)getpid());
if (argc > 1)
{
if (signal(SIGUSR1, sig_usr1) == SIG_ERR)
err_sys("signal(SIGUSR1) error");
if (signal(SIGALRM, sig_alrm) == SIG_ERR)
err_sys("signal(SIGALRM) error");
}
else
{
set_sigaction(SIGUSR1, sig_usr1);
set_sigaction(SIGALRM, sig_alrm);
}
//print signal.
pr_mask("Starting main: ");
if (sigsetjmp(jmpbuf, 1)) {
pr_mask("End main: ");
exit(0);
}
canjmp = 1;
for (;;)
pause();
}

static void
sig_usr1(int signo)
{
time_t starttime;

if (canjmp == 0) {
return;
}

pr_mask("starting sig_usr1: ");
alarm(3);
starttime = time(NULL);
for (;;)
if (time(NULL) > starttime + 5)
break;
pr_mask("finishing sig_usr1: ");
canjmp = 0;
siglongjmp(jmpbuf, 1);
}

static void
sig_alrm(int signo)
{
pr_mask("in sig_arlm: ");
}

void
pr_mask(const char *str)
{
sigset_t sigset;
int errno_save;

errno_save = errno; /* we can be called by signal handlers */
if (sigprocmask(0, NULL, &sigset) < 0)
err_sys("sigprocmask error");

printf("%s", str);
if (sigismember(&sigset, SIGUSR1)) printf("SIGUSR1 ");
if (sigismember(&sigset, SIGALRM)) printf("SIGALRM ");
/* remaining signals can go here */

printf("\n");
errno = errno_save;
}

使用当前 XCode(4.2?)在 MacOS X 10.7.2 上运行,我得到(例如):

$ ./sigtest
PID = 11066
Starting main:
starting sig_usr1: SIGUSR1 SIGALRM
finishing sig_usr1: SIGUSR1 SIGALRM
in sig_arlm: SIGUSR1 SIGALRM
End main:
$ ./sigtest 1
PID = 11067
Starting main:
starting sig_usr1: SIGUSR1
in sig_arlm: SIGUSR1 SIGALRM
finishing sig_usr1: SIGUSR1
End main:
$

关于c - 关于sigsetjmp的一些错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8676459/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com