Обработка сигналов в pthreads

Я не знаю о более изящном пути, чем использование буфера.

, Но размер буфера может иметь значение. Помнить проблемы о Копии Файла Vista? Это - причина, (в основном) изменял размер буфера. Изменения объяснены в это сообщение в блоге . Можно узнать об основных факторах из того сообщения. Однако это только запрашивает копирование файла. В приложениях, вероятно, Вы делаете много копий памяти, так в этом случае, 4 КБ могли быть лучшим размером буфера, , как рекомендуется документацией.NET .

22
задан Niall 13 October 2014 в 12:22
поделиться

2 ответа

Есть несколько проблем с вашим кодом:

  • ptr не инициализирован, поэтому все части ptr-> приведут к сбою программы
  • , которую вы вызываете pthread_kill() немедленно, очень вероятно, до того, как обработчик сигнала был установлен, и в потоке (который имеет неопределенное поведение)
  • вы вызываете printf() из обработчика сигнала, который не гарантированно работает (см. man 7 signal для список безопасных функций)

Это будет работать намного лучше, хотя вам все равно потребуется правильная синхронизация потоков, и, как указано в другом месте, вы должны использовать sigaction():

#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <signal.h>

typedef struct data
{
 char name[10];
 int age;
}data;

void sig_func(int sig)
{
 write(1, "Caught signal 11\n", 17);
 signal(SIGSEGV,sig_func);
}

void func(data *p)
{
 fprintf(stderr, "This is from thread function\n");
 strcpy(p->name,"Mr. Linux");
 p->age=30;
 sleep(2); // Sleep to catch the signal
}

int main()
{
 pthread_t tid;
 pthread_attr_t attr;
 data d;
 data *ptr = &d;

 signal(SIGSEGV,sig_func); // Register signal handler before going multithread
 pthread_attr_init(&attr);
 pthread_create(&tid,&attr,(void*)func,ptr);
 sleep(1); // Leave time for initialisation
 pthread_kill(tid,SIGSEGV);

 pthread_join(tid,NULL);
 fprintf(stderr, "Name:%s\n",ptr->name);
 fprintf(stderr, "Age:%d\n",ptr->age);
}

Редактировать : установить sighandler в основной поток

26
ответ дан 29 November 2019 в 04:46
поделиться

Одна проблема с вашим кодом, о которой еще никто не упомянул, состоит в том, что, хотя блокировка сигнала (и доставка, если вы используете pthread_kill или raise) являются для каждого потока, обработчики сигнала для каждого процесса. Это означает, что они являются очень плохим механизмом для взаимодействия между потоками, особенно если ваш код когда-либо будет использоваться в качестве библиотечного кода, поскольку для библиотеки крайне плохо поведение изменять обработчики сигналов вызывающей стороны.

Также отметим, что использование обработчиков сигналов для связи между потоками имеет неоптимальную производительность по сравнению с другими методами сигнализации потоков, такими как условные переменные или барьеры, потому что существует по крайней мере один дополнительный переход пользователь-ядро-пользователь (когда возвращается обработчик сигнала) .

4
ответ дан 29 November 2019 в 04:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: