Я испытываю реакцию сигналов при использовании с потоками. Я знаю, что семейные функции printf
не являются сигнальными безопасными функциями, но для простоты, которую я использую. Ниже сказано, что
Когда сигнал доставляется многопоточному процессу, который установил обработчик сигнала, ядро произвольно выбирает один
поток в процессе, чтобы доставить сигнал и вызывает
обработчик в этом потоке. Такое поведение обусловлено поддержанием
традиционная семантика сигнала. Это не имеет смысла для
процесс выполнения действий по обработке сигналов несколько раз в
ответ на один сигнал.
Чтобы набрать жирный текст, я пишу следующий основной код, но когда я нажимаю Ctrl-C
, я получаю действительно другой идентификатор потока, а не созданные. Кто это? Почему я не вижу, что другой поток может поймать сигнал.
#include <pthread.h>
#include <stdio.h>
#include <signal.h>
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
int count = 0;
int globerr;
void *inc(void *arg) {
fprintf(stderr, "Thread id = %d\n", (int)pthread_self());
sleep(2);
int error;
for (int i = 0; i < 15; ++i) {
if (error = pthread_mutex_lock(&mtx)) {
globerr = error;
return 0;
}
count++;
printf("thread id = %d, count = %d\n", pthread_self(), count);
if (count == 20) {
printf("thread id = %d, SIGNAL count = %d\n", pthread_self(), count);
pthread_cond_signal(&cv);
}
if (error = pthread_mutex_unlock(&mtx)) {
globerr = error;
return 0;
}
}
}
void* watcher(void *arg) {
fprintf(stderr, "Thread id = %d\n", (int)pthread_self());
sleep(2);
int error;
if (error = pthread_mutex_lock(&mtx)) {
globerr = error;
return 0;
}
while (count < 20) {
printf("watcher thread id = %d, BLOCKING count = %d\n", pthread_self(), count);
pthread_cond_wait(&cv, &mtx);
printf("watcher thread id = %d, UNBLOCKING count = %d\n", pthread_self(), count);
}
printf("watcher thread id = %d, count = %d\n", pthread_self(), count);
if (error = pthread_mutex_unlock(&mtx)) {
globerr = error;
return 0;
}
}
static void signal_handler(int sig){
if (sig == SIGINT)
printf("Caught signal for Ctrl+C, Thread id = %d\n", (int)pthread_self());
pthread_cancel(pthread_self());
}
int main(void) {
struct sigaction sigact;
sigact.sa_handler = signal_handler;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = 0;
sigaction(SIGINT, &sigact, (struct sigaction *)NULL);
pthread_t t[3];
for (int i = 0; i < 2; ++i) {
pthread_create(&t[i], 0, inc, 0);
}
pthread_create(&t[2], 0, watcher, 0);
sleep(3);
for (int i = 0; i < 3; ++i) {
pthread_join(t[i], 0);
}
}
Пример вывода,
MacBook-Pro-2:cmake-build-debug soner$ ./client
Thread id = 171921408
Thread id = 172457984
Thread id = 172994560
^CCaught signal for Ctrl+C, Thread id = 360719808
^CCaught signal for Ctrl+C, Thread id = 171921408
^CCaught signal for Ctrl+C, Thread id = 172457984
^CCaught signal for Ctrl+C, Thread id = 172994560
Кто такой 360719808
?