Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中使用带计时器的sigaction时遇到问题_C_Timer_Signals - Fatal编程技术网

在C中使用带计时器的sigaction时遇到问题

在C中使用带计时器的sigaction时遇到问题,c,timer,signals,C,Timer,Signals,这是我的密码。正如你所看到的,这很简单。 我要程序打印点,直到它捕捉到信号。 但我的程序似乎不起作用。 我怎样才能修好它 void handler(int code) { fprintf(stdout, "signal catched"); exit(0); } int main() { struct itimerval new, old; struct sigaction newact; sigemptyset(&newact.sa_mask)

这是我的密码。正如你所看到的,这很简单。 我要程序打印点,直到它捕捉到信号。 但我的程序似乎不起作用。 我怎样才能修好它

void handler(int code) {
    fprintf(stdout, "signal catched");
    exit(0);
}

int main() {
    struct itimerval new, old;
    struct sigaction newact;
    sigemptyset(&newact.sa_mask);
    newact.sa_flags = 0;
    newact.sa_handler = handler;
    sigaction(SIGPROF, &newact,NULL);
    new.it_interval.tv_usec = 0;
    new.it_interval.tv_sec = 0;
    new.it_value.tv_usec = 0;
    new.it_value.tv_sec = (long int) 3;
    setitimer(ITIMER_PROF, &new, &old);

    while (1)
    {
        fprintf(stdout, ". ");
    }
    return 0;
}
这个信号处理器

void handler(int code) {
    fprintf(stdout, "signal catched");
    exit(0);
}
违反以下标准:

标准库中的函数不保证可重入,可能会修改具有静态或线程存储持续时间的对象

作为:

因此,信号处理程序通常不能调用标准库函数

POSIX允许从信号处理程序中调用异步信号安全函数:

Per:

。。。该行为未定义。。。如果信号处理程序调用本标准中定义的任何函数(下表中列出的函数之一除外)

_Exit()
_exit()
abort()
accept()
access()
aio_error()
aio_return()
aio_suspend()
alarm()
bind()
cfgetispeed()
cfgetospeed()
cfsetispeed()
cfsetospeed()
chdir()
chmod()
chown()
clock_gettime()
close()
connect()
creat()
dup()
dup2()
execl()
execle()
execv()
execve()
faccessat()
fchdir()
fchmod()
fchmodat()
fchown()
fchownat()
fcntl()
fdatasync()
fexecve()
ffs()
fork()
fstat()
fstatat()
fsync()
ftruncate()
futimens()
getegid()
geteuid()
getgid()
getgroups()
getpeername()
getpgrp()
getpid()
getppid()
getsockname()
getsockopt()
getuid()
htonl()
htons()
kill()
link()
linkat()
listen()
longjmp()
lseek()
lstat()
memccpy()
memchr()
memcmp()
memcpy()
memmove()
memset()
mkdir()
mkdirat()
mkfifo()
mkfifoat()
mknod()
mknodat()
ntohl()
ntohs()
open()
openat()
pause()
pipe()
poll()
posix_trace_event()
pselect()
pthread_kill()
pthread_self()
pthread_sigmask()
raise()
read()
readlink()
readlinkat()
recv()
recvfrom()
recvmsg()
rename()
renameat()
rmdir()
select()
sem_post()
send()
sendmsg()
sendto()
setgid()
setpgid()
setsid()
setsockopt()
setuid()
shutdown()
sigaction()
sigaddset()
sigdelset()
sigemptyset()
sigfillset()
sigismember()
siglongjmp()
signal()
sigpause()
sigpending()
sigprocmask()
sigqueue()
sigset()
sigsuspend()
sleep()
sockatmark()
socket()
socketpair()
stat()
stpcpy()
stpncpy()
strcat()
strchr()
strcmp()
strcpy()
strcspn()
strlen()
strncat()
strncmp()
strncpy()
strnlen()
strpbrk()
strrchr()
strspn()
strstr()
strtok_r()
symlink()
symlinkat()
tcdrain()
tcflow()
tcflush()
tcgetattr()
tcgetpgrp()
tcsendbreak()
tcsetattr()
tcsetpgrp()
time()
timer_getoverrun()
timer_gettime()
timer_settime()
times()
umask()
uname()
unlink()
unlinkat()
utime()
utimensat()
utimes()
wait()
waitpid()
wcpcpy()
wcpncpy()
wcscat()
wcschr()
wcscmp()
wcscpy()
wcscspn()
wcslen()
wcsncat()
wcsncmp()
wcsncpy()
wcsnlen()
wcspbrk()
wcsrchr()
wcsspn()
wcsstr()
wcstok()
wmemchr()
wmemcmp()
wmemcpy()
wmemmove()
wmemset()
write()
上表中未列出的任何功能在信号方面可能不安全

(请注意)

可能发生的情况是,您的信号处理程序中断了此循环中的
fprintf()
调用:

while (1)
{
    fprintf(stdout, ". ");
}
这会导致死锁,因为主
while()
循环中的
fprintf()
持有一个锁,因此当调用信号处理程序时,它会阻止对
fprintf()
的调用,等待锁释放,而这是无法实现的,因为持有锁的
fprintf()
调用被信号中断


您也不能从信号处理程序中安全地调用
exit()

以下建议的代码:

#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>


void handler(int code) 
{
    (void)code;  // to avoid compiler message about unused parameter

    write( 1, "signal catched", sizeof( "signal catched" ) );
    _exit(0);  // notice the leading underscore
}

int main( void ) // use a valid signature for `main()`
{
    struct itimerval new, old;
    struct sigaction newact;

    sigemptyset(&newact.sa_mask);
    newact.sa_flags = 0;
    newact.sa_handler = handler;
    sigaction(SIGPROF, &newact,NULL);
    new.it_interval.tv_usec = 0;
    new.it_interval.tv_sec = 0;
    new.it_value.tv_usec = 0;
    new.it_value.tv_sec = (long int) 3;
    setitimer(ITIMER_PROF, &new, &old);

    while (1)
    {
        fprintf(stdout, ". ");
    }
    return 0;
}
  • 干净地编译
  • 执行所需的功能
  • 不违反“信号”处理程序只使用线程安全函数的要求
  • 注:<代码>新< /代码>是一个非常不好的选择,因为它是“C++中的保留词”。 发布代码时,始终发布所需的
    #include
    语句

    现在,拟议的守则:

    #include <stdio.h>
    #include <signal.h>
    #include <sys/time.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    
    void handler(int code) 
    {
        (void)code;  // to avoid compiler message about unused parameter
    
        write( 1, "signal catched", sizeof( "signal catched" ) );
        _exit(0);  // notice the leading underscore
    }
    
    int main( void ) // use a valid signature for `main()`
    {
        struct itimerval new, old;
        struct sigaction newact;
    
        sigemptyset(&newact.sa_mask);
        newact.sa_flags = 0;
        newact.sa_handler = handler;
        sigaction(SIGPROF, &newact,NULL);
        new.it_interval.tv_usec = 0;
        new.it_interval.tv_sec = 0;
        new.it_value.tv_usec = 0;
        new.it_value.tv_sec = (long int) 3;
        setitimer(ITIMER_PROF, &new, &old);
    
        while (1)
        {
            fprintf(stdout, ". ");
        }
        return 0;
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    无效处理程序(int代码)
    {
    (void)code;//避免有关未使用参数的编译器消息
    写入(1,“信号捕获”,sizeof(“信号捕获”);
    _退出(0);//注意前面的下划线
    }
    int main(void)//对`main()使用有效的签名`
    {
    结构itimerval新、旧;
    结构sigaction newact;
    sigemptyset(和newact.sa_面具);
    newact.sa_标志=0;
    newact.sa_handler=handler;
    sigaction(SIGPROF和newact,NULL);
    new.it\u interval.tv\u usec=0;
    new.it_interval.tv_sec=0;
    new.it_value.tv_usec=0;
    new.it_value.tv_sec=(long int)3;
    setitimer(ITIMER_教授、新、旧);
    而(1)
    {
    fprintf(标准符号“.”);
    }
    返回0;
    }
    
    典型的代码运行结果是:

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 捕捉到的信号