2017-06-19 138 views
1

我正在构建一个用C-UNIX编写的通用程序(使用Linux,所以我不在乎BSD或WIN函数),它创建了两个线程来处理与服务器的通信。调用SIGINT时终止线程 - C

void init_threads(int socket_desc) { 

    pthread_t chat_threads[2]; 

    ret = pthread_create(&chat_threads[0], NULL, receiveMessage, (void*)(long)socket_desc); 
    PTHREAD_ERROR_HELPER(ret, "Errore creazione thread ricezione messaggi"); 

    ret = pthread_create(&chat_threads[1], NULL, sendMessage, (void*)(long)socket_desc); 
    PTHREAD_ERROR_HELPER(ret, "Errore creazione thread invio messaggi"); 

} 

由于这一计划将在shell启动我要实现CTRL-C可能性,所以做我这行代码:

signal(SIGINT,kill_handler); 
// and its related function 
void kill_handler() { 
     // retrive threads_id 
     // call pthread_exit on the two threads 
     printf("Exit from program cause ctrl-c, bye bye\n"); 
     exit(EXIT_SUCCESS); 
     } 

我的问题是如何发现的事件处理函数中的线程ID,调用pthread_exit还是应该使用别的东西?

+2

可能重复[如何正确终止信号处理程序中的线程?](https://stackoverflow.com/questions/25950621/how-to-properly-terminate-a-thread-in-a-signal-处理器) – Gaurav

+1

信号被传递给主线程;退出()在那里,操作系统会为你做清理。 – Ctx

+0

我发誓我真的没有找到20分钟深搜索后的重复。因为在我的计划被誉为费利克斯Palmen比@Ctx的意见更好的答案我使用的插座,如果有开他们的连接插座将保持开放,即使threre是没有听一小段时间。无论如何,感谢大家。 – Thecave3

回答

2

不要从信号处理程序中调用pthread_exit()!不要求异步信号安全,请参阅signal-safety

一般来说,你应该在信号处理程序中尽可能少地使用。常见的习惯用法是设置一个标志,在您的主循环中定期检查,例如

volatile sig_atomic_t exitRequested = 0; 

void signal_handler(int signum) 
{ 
    exitRequested = 1; 
} 

int main(void) 
{ 
    // init and setup signals 

    while (!exitRequested) 
    { 
     // do work 
    } 

    // cleanup 
} 

此外,使用sigaction()安装信号处理程序。请参阅signal(),以避免使用它。

+0

感谢您的有用链接和解释 – Thecave3

+0

我知道这与我的问题无关,但您能否向我解释什么是sig_atomic_t类型,以及为什么使用该类型而不是int?我知道32位机器上的整数是4个字节,这是更紧的? – Thecave3

+1

这是一种保证读取和写入* single *指令的类型。有一个很好的机会,它只是一个'typedef'到'int',但有可能是其中'int'需要多于一个指令读取/写入系统(例如,在8位架构,其中'int'有16位) - 对于信号处理程序和主程序之间的一致值,只需使用'volatile sig_atomic_t'。 –