프로세스와 스레드 간의 신호 처리를 배우려고합니다. 몇 가지 질문에 대한 답은 그것을 더 잘 이해하는 데 도움이 될 것입니다.pthread 간의 신호 처리
프로세스가 프로세스 그룹에 신호를 보내고 여러 프로세스가 동일한 신호를 수신 할 수 있음을 알고 있지만 스레드에 대해 확신하지 못합니다.
- 모든 pthreads로 보낸 신호를 동시에 둘 이상의 pthread에서 처리 할 수 있습니까?
I 설치 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;
}
필자는 만트라가 '신호가 처리됩니다'라고 생각하고 신호를 무시하지 않는 스레드로 한 번 배달됩니다. –
신호가 특정 스레드 또는 모든 스레드로 전송 될 수 있다고 확신합니다. 단 하나만 처리 할 수 있는지는 모르지만 모두 신호를 수신 할 수 있다고 생각합니다. – OwlsCIS
@ 0d0a 신호 핸들러는 신호를 차단 한 다음 폴링 할 때 관련이 없습니다. – o11c