【问题标题】:Terminate threads when SIGINT is called - C调用 SIGINT 时终止线程 - C
【发布时间】:2017-06-19 11:20:01
【问题描述】:

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

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 是否正确,还是应该使用其他方法?

【问题讨论】:

  • 信号被传递到主线程;只需 exit() 那里,操作系统将为您进行清理。
  • 我发誓,经过 20 分钟的深度搜索,我真的没有找到副本。 Felix Palmen 的回答比@Ctx 的评论更好,因为在我的程序中,我使用的是套接字,如果在它们上打开了连接,即使没有可听的内容,套接字也会在短时间内保持打开状态。无论如何,谢谢大家。

标签: c linux multithreading signals posix


【解决方案1】:

不要从信号处理程序调用pthread_exit()!它不需要是async-signal-safe,参见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() 了解不使用它的原因。

【讨论】:

  • 感谢有用的链接和解释
  • 我知道这与我的问题无关,但您能向我解释一下什么是 sig_atomic_t 类型以及为什么使用它而不是 int 吗?我知道整数在 32 位机器上是 4 字节,这更紧?
  • 这是一种保证通过single指令进行读写的类型。很有可能它只是 typedefint,但在某些系统中,int 可能需要多条指令来读/写(例如,在 8 位架构上,int 有 16 位)-对于信号处理程序和主程序之间的一致值,请始终使用volatile sig_atomic_t
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-22
  • 2017-04-08
  • 1970-01-01
相关资源
最近更新 更多