【问题标题】:C++ main program with a thread requires Ctrl+C twice in order to exit带有线程的 C++ 主程序需要 Ctrl+C 两次才能退出
【发布时间】:2015-11-14 01:23:13
【问题描述】:

我正在运行下面的 C++ 程序,在 Ubuntu 上它里面有一个线程。
为什么需要两次 Ctrl+C 调用才能退出程序?
我注意到我向它发出的第一个 Ctrl+C 只会关闭 myThread。

注意:我确信 myThread 线程在第一个 Ctrl+C 后不复存在。这是我通过 ps aux 发现的。我只在第二个 Ctrl+C
之后得到打印 main_recv_sigint: Executed 在我的生产代码中,我正在执行 python 代码而不是 sleep 1000

如何让单个 Ctrl+C 完全关闭它?

#include <iostream>
#include <signal.h>
#include <thread>
#include <cstdlib>
#include "unistd.h"
#include <cstdio>

void *myThread(void *params)
{
    std::string cmd = "sleep 1000";
    if (system (cmd.c_str ()));

    return NULL;
}

void main_recv_sigint (int sig);
bool runMainThread = true;

int main(int argc, char *argv[])
{
    pthread_t threadID;
    pthread_create(&threadID, NULL, myThread, NULL);

    signal(SIGINT, main_recv_sigint);

    while (runMainThread) {
        while (runMainThread)
            sleep(2);

        if (!runMainThread)
            break;
    }

    printf("Waiting for myThread() to exit\n");
    pthread_join(threadID, NULL);
    printf("Wait for myThread() exit done\n");

    return 0;
}

void main_recv_sigint (int sig)
{
    printf("main_recv_sigint: Executed\n");
    runMainThread = false;
    return;
}

【问题讨论】:

  • 附带说明,如果您使用 pthreads,那么您应该包含声明 API 的标头。
  • 确实不是个好主意 ` printf("main_recv_sigint: Executed\n"); ` 在信号处理程序中。
  • 我明白了。我放置打印语句主要是为了能够调试这个..

标签: c++ multithreading pthreads signals


【解决方案1】:

有两件事可以解释这种行为:

  1. system causes the calling process to ignore SIGINT 在等待其子节点终止时
  2. Ctrl-C 向整个前台进程组发送一个 SIGINT,其中包括您的程序及其子程序 sleep

所以,第一个 Ctrl-C 杀死了子 sleep 进程,但被父进程忽略了——永远不会调用处理程序——这在不知不觉中继续循环。第二个 Ctrl-C 传递了一个 SIGINT,它由父级处理,如您所料。

至于你的第二个问题,“我怎样才能让一个 Ctrl+C 完全关闭它?”,你需要重新设计。 system 是一个旧函数,设计时没有考虑线程,有点特殊,可能不适合您的用例。

【讨论】:

  • 请注意,用sleep(1000) 替换system 调用仍然无法正确结束Ctrl+C 上的进程,因为信号处理程序实际上并没有结束线程——它只是结束了whilemain 中循环。
  • @SanderDeDycker,对,但我认为 OP 不会那样做。 (当然,sleep 1000 只是一些长期运行的外部进程的替身。)
  • 那个长时间运行的进程可能也必须被信号处理程序中断,就像睡眠一样。要点是现在的信号处理程序不足以让 Ctrl+C 完全关闭进程(这是 OP 想要的) - 信号处理程序还必须中断和关闭任何线程和子进程任何合适的方式。
  • 在我的实际代码中,我使用系统调用python脚本。我怎么能用系统做到这一点?对此有任何想法..
猜你喜欢
  • 2012-12-22
  • 2012-06-11
  • 2021-02-20
  • 1970-01-01
  • 1970-01-01
  • 2015-07-20
  • 2017-07-03
  • 2020-09-22
  • 1970-01-01
相关资源
最近更新 更多