繁体   English   中英

子线程中的信号处理程序

[英]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)当线程发送SIGINTt_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM