【发布时间】:2014-11-29 15:53:46
【问题描述】:
我正在尝试学习进程和线程之间的信号处理。几个问题的答案将帮助我更好地理解它。
我知道一个进程可以向进程组发送信号并允许多个进程接收相同的信号,但我不确定线程。
- 发送到所有 pthread 的信号是否可以同时由多个 pthread 处理?
我设置我的程序使用pthread_sigmask() 阻止所有信号,我有两个线程使用sigwait(SIGUSR1) 等待信号,并且我让主线程发送 SIGUSR1 信号。当只有一个线程处理信号时,似乎一切正常(我在另一个线程中注释掉了代码),但是当两个线程都运行sigwait() 代码时,它挂起或终止太快。
代码贴在下面。
sig_atomic_t signals = 0;
sig_atomic_t sigusr1_signals = 0;
sig_atomic_t sigusr2_signals = 0;
sig_atomic_t count = 0;
sig_atomic_t totalcount = 0;
sigset_t globalset;
int WAIT = 1; /* false = 0, true = 1 */
static int SIGNALS_SENT = 0;
static int SIGNALS_RECEIVED = 0;
void *sig1handler1(void *argv);
void *reporterhandler(void *argv);
int random_number(int min, int max);
int main(void) {
pthread_t threads[2]; /* create an array to store a number of threads */
//int *p_status = &status;
sigfillset(&globalset);
pthread_sigmask(SIG_BLOCK, &globalset, NULL);
/* Generate signal handling threads */
if (pthread_create(&threads[0], NULL, &sig1handler1, NULL) > 0)
{
printf("Thread creation failure!\n");
return -1;
}
/* create reporting thread */
if (pthread_create(&threads[1], NULL, &reporterhandler, NULL) > 0)
{
printf("Thread creation failure!\n");
return -1;
}
/* Signal all threads to begin work concurrently */
WAIT = 0;
int c = 0;
while(c < 100)
{
int value = random_number(1, 2);
if (value == 1)
kill(0, SIGUSR1);
else
kill(0, SIGUSR2);
SIGNALS_SENT++;
c++;
usleep(10000);
}
kill(0, SIGINT);
/* Wait for each thread to finish and join */
int i = 0;
for(i = 0; i < 2; i++)
{
if (pthread_join(threads[i], NULL) > 0)
{
printf("Thread [%u] join failure!\n", (unsigned int)threads[i]);
return -1;
}
printf("THREAD [%u] returned.\n", (unsigned int)threads[i]);
}
printf("Parent Process [%d] exiting successfully.\n", getpid());
return EXIT_SUCCESS;
}
void *sig1handler1(void *argv)
{
pthread_t tid = pthread_self();
printf("THREAD[%u] sig1handler1: waiting for signal to do some work...\n", (unsigned int)tid);
// sigset_t myset;
// sigfillset(&myset);
// sigdelset(&myset, SIGINT);
// sigdelset(&myset, SIGUSR1);
// pthread_sigmask(SIG_SETMASK, &myset, NULL);
/* Wait for a signal to start work */
while (WAIT);
int sig;
int count = 0;
while(1)
{
sigwait(&globalset, &sig);
if (sig == SIGUSR1)
{
sigusr1_signals++;
signals++;
count++;
//printf("thread1: caught SIGUSR1 signal!\n");
}
else if (sig == SIGINT)
{
printf("thread1: caught SIGINT signal, detected SIGUSR1 %d times, and terminating!\n", count); pthread_exit(NULL);
}
}
//printf("THREAD[%u] sig1handler1: doing some work!\n", (unsigned int)tid);
//return (void *)EXIT_SUCCESS;
//return (void *)NULL;
pthread_exit(NULL);
}
void *reporterhandler(void *argv)
{
pthread_t tid = pthread_self();
printf("THREAD[%u] reporter: waiting for signal to do some work...\n", (unsigned int)tid);
int sig;
int count = 0;
// sigset_t myset;
// sigfillset(&myset);
// sigdelset(&myset, SIGINT);
// sigdelset(&myset, SIGUSR1);
// sigdelset(&myset, SIGUSR2);
// pthread_sigmask(SIG_SETMASK, &myset, NULL);
/* Wait for a signal to start work */
while (WAIT);
while(1)
{
sigwait(&globalset, &sig);
if (sig == SIGUSR1)
{
sigusr1_signals++;
signals++;
count++;
totalcount++;
SIGNALS_RECEIVED++;
}
else if (sig == SIGUSR2)
{
sigusr2_signals++;
signals++;
count++;
totalcount++;
SIGNALS_RECEIVED++;
}
else if (sig == SIGINT)
{
printf("Reporter: SIGUSR1 detected %d times\n", sigusr1_signals);
printf("Reporter: SIGUSR2 detected %d times\n", sigusr2_signals);
printf("Reporter: detected %d signals\n", totalcount);
printf("Reporter: SIGNALS_SENT %d \n", SIGNALS_SENT);
printf("Reporter: SIGNALS_REC %d \n", SIGNALS_RECEIVED);
pthread_exit(NULL);
}
/* Display Report after detecting 10 signals */
if (count == 10)
sigusr1_signals, sigusr2_signals);
count = 0;
}
}
//printf("THREAD[%u] reporter: doing some work!\n", (unsigned int)tid);
pthread_exit(NULL);
}
int random_number(int min, int max)
{
if (min < max)
{
max = max + 1; /* include the max value */
return (rand() % (max - min)) + min;
}
return -1;
}
【问题讨论】:
-
我相信口头禅是“信号被发送到进程”,并且将被传递一次到不忽略信号的线程。
-
我比较确定信号可以发送到特定线程或所有线程。不知道是不是只有一个人可以处理,但我想他们都可以接收到信号。
-
@0d0a 信号处理程序在您阻止信号然后轮询它们时不相关。
-
您好 o11c,感谢您提供的信息。我知道您使用其中一种。我的代码使用名称 sighandler 来表示函数,但它们实际上是由线程完成的工作,它坐在那里等待信号。
标签: c multithreading pthreads signals signal-handling