kin*_*er1 22 c signals pthreads
我已经创建了一个pthread,并在其中安装了一个信号处理程序,就像我们在main( )函数中一样.线程的信号处理程序是一个单独的函数.令人惊讶的是,它不起作用,即线程的信号处理程序无法捕获信号.
这是代码:
#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)
{
printf("Caught signal: %d\n",sig);
signal(SIGSEGV,sig_func);
}
void func(data *p)
{
printf("This is from thread function\n");
signal(SIGSEGV,sig_func); // Register signal handler inside thread
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 *ptr;
pthread_attr_init(&attr);
pthread_create(&tid,&attr,(void*)func,ptr);
pthread_kill(tid,SIGSEGV);
pthread_join(tid,NULL);
printf("Name:%s\n",ptr->name);
printf("Age:%d\n",ptr->age);
}
Run Code Online (Sandbox Code Playgroud)
输出:
分段错误(这意味着信号不会被处理程序捕获)
sam*_*var 26
您的代码有几个问题:
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);
}
Run Code Online (Sandbox Code Playgroud)
编辑:在主线程中安装sighandler
sar*_*old 10
我认为问题的核心是信号作为一个整体传递给整个过程,而不是单个线程.通常,提名单个线程来处理所有信号; 所有其他线程(包括主线程)需要使用阻塞信号pthread_sigmask().
您可以设置掩码以阻止所有信号,启动信号处理程序线程,取消屏蔽您希望处理的信号,然后返回主线程,启动您需要的所有其他线程.他们将从主线程继承"阻止所有信号"掩码.
顺便说一下,是时候离开signal(3)并切换到sigaction(2),它具有可靠的语义并且更好地标准化.(因此更便携.)
没有人提到过你的代码的一个问题是,虽然信号阻塞(和传递,如果你使用pthread_kill或raise)是每个线程的,但信号处理程序是每个进程的。这意味着它们对于线程间通信来说是一种非常糟糕的机制,尤其是如果您的代码将被用作库代码,因为库更改调用者的信号处理程序是非常糟糕的行为。
另请注意,与其他线程信号方法(如条件变量或障碍)相比,使用信号处理程序进行线程之间的通信具有次优性能,因为至少有一个额外的用户-内核-用户转换(当信号处理程序返回时)。
| 归档时间: |
|
| 查看次数: |
77861 次 |
| 最近记录: |