[英]signal handler in child thread
我尝试在下面的代码中为子线程安装SIGINT处理程序。 我希望子线程在从父进程接收SIGINT时打印hello。 然而,没有任何结果,程序立即退出。
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
typedef struct proxy_node_t{
pthread_t sub_thread;
pthread_t p_self;
}proxy_node;
proxy_node* proxy;
static void proxy_singnal_handler(){
printf("Hello\n");
return;
}
static void* t_consensus(void *arg){
signal(SIGINT,proxy_singnal_handler);
sleep(1);
return NULL;
}
int main(int argc, char **argv)
{
proxy = (proxy_node*)malloc(sizeof(proxy_node));
proxy->p_self = pthread_self();
pthread_create(&proxy->sub_thread,NULL,t_consensus,NULL);
pthread_kill(proxy->sub_thread,SIGINT);
sleep(1);
return 0;
}
有几个问题。
1)信号处理程序签名不正确。 它应该采用int
而你没有参数定义它。 即
static void proxy_singnal_handler(){
应该
static void proxy_singnal_handler(int sig){
2)您不能从信号处理程序(在您的情况下为printf()
中调用非异步信号安全的函数。 有关详细信息,请参阅信号(7) 。 您可以改为使用write(2)
来打印该消息:
printf("Hello\n");
可:
write(1, "Hello\n", 6);
3)当主线程发送SIGINT
, t_consensus
线程可能甚至没有启动。 因此, signal()
可能尚未安装。 因此,您需要确保在 pthread_kill()
发送SIGINT
之前安装了signal()
。
为了演示它,我添加了一些睡眠调用(请参阅代码中的注释)。 但请注意,sleep() 不是一种很好的同步方法,如果你打算改编这个例子,那么你应该使用条件变量。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>
typedef struct proxy_node_t{
pthread_t sub_thread;
pthread_t p_self;
}proxy_node;
proxy_node* proxy;
static void proxy_singnal_handler(int sig){
write(1, "Hello\n", 6);
return;
}
static void* t_consensus(void *arg){
signal(SIGINT,proxy_singnal_handler);
while(1); /* infinite loop */
return NULL;
}
int main(int argc, char **argv)
{
proxy = (proxy_node*)malloc(sizeof(proxy_node));
proxy->p_self = pthread_self();
pthread_create(&proxy->sub_thread,NULL,t_consensus,NULL);
sleep(2); /* delay to ensure signal handler is installed */
pthread_kill(proxy->sub_thread,SIGINT);
sleep(2); /* delay to ensure signal gets executed before the process exits */
return 0;
}
因为@Maxim Egorushkin希望看到一个优雅地退出并使用信号量的解决方案:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>
#include <semaphore.h>
typedef struct proxy_node_t{
pthread_t sub_thread;
pthread_t p_self;
}proxy_node;
proxy_node* proxy;
static void proxy_singnal_handler(int sig)
{
write(1, "Hello\n", 6);
return;
}
sem_t sema1;
sem_t sema2;
static void* t_consensus(void *arg)
{
signal(SIGINT,proxy_singnal_handler);
sem_post(&sema1); /*notify main thread that signal-handler is installed*/
sem_wait(&sema2); /*ensure thread exists to be pthread_kill'ed, could use sigsuspend instead*/
return NULL;
}
int main(int argc, char **argv)
{
sem_init(&sema1, 0, 0);
sem_init(&sema2, 0, 0);
proxy = (proxy_node*)malloc(sizeof(proxy_node));
proxy->p_self = pthread_self();
pthread_create(&proxy->sub_thread,NULL,t_consensus,NULL);
sem_wait(&sema1); /*wait until the thread has installed the signal handler*/
pthread_kill(proxy->sub_thread,SIGINT);
sem_post(&sema2); /*not strictly necessary if the thread uses sigsuspend*/
pthread_join(proxy->sub_thread, NULL);
free(proxy); /*not strictly necessary before exiting*/
sem_destroy(&sema1);
sem_destroy(&sema2);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.