为什么在辅助线程中 pause(2) 不是 return?
Why does pause(2) not return in secondary thread?
考虑我设置的这个例子来说明这一点。
#define _POSIX_C_SOURCE 199506L
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
void hand(int sig);
void *thrfn(void *arg);
int main(void)
{
struct sigaction act;
struct itimerval timer;
sigset_t mask;
pthread_t thr;
act.sa_handler = hand;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGALRM, &act, NULL);
/* error checking omitted */
timer.it_interval.tv_sec = 1;
timer.it_interval.tv_usec = 500000;
timer.it_value = timer.it_interval;
/* ultimately I want to build a loop; hence repeating */
setitimer(ITIMER_REAL, &timer, NULL);
sigemptyset(&mask);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
/* why doesn't this prevent SIGALRM from interrupting main? */
pthread_create(&thr, NULL, thrfn, NULL);
puts("Main thread done.");
getchar();
return 0;
}
void hand(int sig)
{
(void)sig;
write(STDOUT_FILENO, "Handler handled.\n", 17);
}
void *thrfn(void *arg)
{
sigset_t mask;
(void)arg;
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
/* why doesn't this make pause() return in this thread? */
pause();
puts("Off thread's pause returned.");
pthread_exit(NULL);
}
这是使用 gcc 编译的输出:
Main thread done.
Handler handled.
消息之间大约间隔一秒半。
为什么我的第二个线程 pause
从来没有 returns?
我猜错误是在 pthread_sigmask
的用法上。使用 SIG_BLOCK
和 SIG_UNBLOCK
而不是 SIG_SETMASK
程序的行为符合您的预期。
#define _POSIX_C_SOURCE 199506L
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
void hand(int sig);
void *thrfn(void *arg);
int main(void)
{
struct sigaction act;
struct itimerval timer;
sigset_t mask;
pthread_t thr;
act.sa_handler = hand;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGALRM, &act, NULL);
/* error checking omitted */
timer.it_interval.tv_sec = 1;
timer.it_interval.tv_usec = 500000;
timer.it_value = timer.it_interval;
/* ultimately I want to build a loop; hence repeating */
setitimer(ITIMER_REAL, &timer, NULL);
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
pthread_sigmask(SIG_BLOCK, &mask, NULL);
/* This prevent SIGALARM interrupring the main */
pthread_create(&thr, NULL, thrfn, NULL);
puts("Main thread done.");
getchar();
return 0;
}
void hand(int sig)
{
(void)sig;
write(STDOUT_FILENO, "Handler handled.\n", 17);
}
void *thrfn(void *arg)
{
sigset_t mask;
(void)arg;
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
pthread_sigmask(SIG_UNBLOCK, &mask, NULL);
/* This make the pause() return on SIGALARM */
pause();
puts("Off thread's pause returned.");
pthread_exit(NULL);
}
该程序给出以下输出:
$ ./test
Main thread done.
Handler handled.
Off thread's pause returned.
特别是:
sigemptyset(&mask);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
您正在取消阻塞主线程中的所有信号。同时,与:
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
您仅 SIGALARM
在子线程上阻塞。这可能与您想做的相反。
请记住,使用 SIG_SETMASK
您指定了一组被阻止的信号。
考虑我设置的这个例子来说明这一点。
#define _POSIX_C_SOURCE 199506L
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
void hand(int sig);
void *thrfn(void *arg);
int main(void)
{
struct sigaction act;
struct itimerval timer;
sigset_t mask;
pthread_t thr;
act.sa_handler = hand;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGALRM, &act, NULL);
/* error checking omitted */
timer.it_interval.tv_sec = 1;
timer.it_interval.tv_usec = 500000;
timer.it_value = timer.it_interval;
/* ultimately I want to build a loop; hence repeating */
setitimer(ITIMER_REAL, &timer, NULL);
sigemptyset(&mask);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
/* why doesn't this prevent SIGALRM from interrupting main? */
pthread_create(&thr, NULL, thrfn, NULL);
puts("Main thread done.");
getchar();
return 0;
}
void hand(int sig)
{
(void)sig;
write(STDOUT_FILENO, "Handler handled.\n", 17);
}
void *thrfn(void *arg)
{
sigset_t mask;
(void)arg;
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
/* why doesn't this make pause() return in this thread? */
pause();
puts("Off thread's pause returned.");
pthread_exit(NULL);
}
这是使用 gcc 编译的输出:
Main thread done.
Handler handled.
消息之间大约间隔一秒半。
为什么我的第二个线程 pause
从来没有 returns?
我猜错误是在 pthread_sigmask
的用法上。使用 SIG_BLOCK
和 SIG_UNBLOCK
而不是 SIG_SETMASK
程序的行为符合您的预期。
#define _POSIX_C_SOURCE 199506L
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
void hand(int sig);
void *thrfn(void *arg);
int main(void)
{
struct sigaction act;
struct itimerval timer;
sigset_t mask;
pthread_t thr;
act.sa_handler = hand;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGALRM, &act, NULL);
/* error checking omitted */
timer.it_interval.tv_sec = 1;
timer.it_interval.tv_usec = 500000;
timer.it_value = timer.it_interval;
/* ultimately I want to build a loop; hence repeating */
setitimer(ITIMER_REAL, &timer, NULL);
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
pthread_sigmask(SIG_BLOCK, &mask, NULL);
/* This prevent SIGALARM interrupring the main */
pthread_create(&thr, NULL, thrfn, NULL);
puts("Main thread done.");
getchar();
return 0;
}
void hand(int sig)
{
(void)sig;
write(STDOUT_FILENO, "Handler handled.\n", 17);
}
void *thrfn(void *arg)
{
sigset_t mask;
(void)arg;
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
pthread_sigmask(SIG_UNBLOCK, &mask, NULL);
/* This make the pause() return on SIGALARM */
pause();
puts("Off thread's pause returned.");
pthread_exit(NULL);
}
该程序给出以下输出:
$ ./test
Main thread done.
Handler handled.
Off thread's pause returned.
特别是:
sigemptyset(&mask);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
您正在取消阻塞主线程中的所有信号。同时,与:
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
您仅 SIGALARM
在子线程上阻塞。这可能与您想做的相反。
请记住,使用 SIG_SETMASK
您指定了一组被阻止的信号。