簡體   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