C++ 分离的线程可以通过哪些可能的方式发出它正在终止的信号?

Posted

技术标签:

【中文标题】C++ 分离的线程可以通过哪些可能的方式发出它正在终止的信号?【英文标题】:C++ What possible ways can a detached thread signal it is terminating? 【发布时间】:2021-03-16 14:00:35 【问题描述】:

我对此有三个初步的想法

首先是某种计数器? (也许使用互斥锁?) 某种信号量? (我不太了解这些)或者可能是promise/future 组合 其他类型的信号/槽机制,类似于由 CTRL-C(SIGINT 等)创建的信号

我正在开发一些利用分离线程来完成某些工作的软件。不幸的是,线程并没有很好地清理,它们只是在执行结束时退出。这对于一个方向的通信很好(即;main() 可以先退出),但不会反过来工作 - 目前main() 无法知道线程何时完成工作并优雅地退出。

扩展这些要点...

我最初的想法是有一个受保护的变量区域 - 可以是一个计数器或一组标志,每个线程一个,并使用互斥锁访问这些。如果每个分离的线程使用一个变量来表示线程工作的结束,甚至可能不需要互斥锁,因为main() 将“轮询”这些变量,这是一种只读操作。只有分离的线程本身需要写访问。如果多个分离线程使用相同的计数器/变量,则需要使用互斥体。

我的下一个想法是使用信号量(我真的一无所知)或promise/future 组合,我认为可以作为一种选择。

最后的想法是某种信号机制,比如可能“窃取”一个 SIGxyz 信号(如 SIGINT)并使用它来传达线程执行结束的某种方式。不过我对这个没有信心。

我的问题是真的 - 这应该怎么做?这个问题的典型工程解决方案是什么?

(最后的想法:使用文件还是管道?看起来有点复杂?)

【问题讨论】:

您想要某种“自动”信号,还是可以轮询状态? 我还没有看到使用分离线程的案例,这不是设计缺陷。包括我自己使用的分离线程,这是设计缺陷。 你能访问/修改线程实现吗? en.cppreference.com/w/cpp/thread/condition_variable 【参考方案1】:

也许我忽略了这个问题,但我认为您可以使用原子变量作为标志来通知分离线程的终止。

类似于以下示例:

#include <thread>
#include <iostream>
#include <atomic>

int main()

    // Define a flag to notify detached thread's termination
    std::atomic_bool term_flag;

    // Define some function to run concurrently
    auto func = [&term_flag]()
        std::this_thread::sleep_for(std::chrono::seconds(2));
        term_flag = true;
    ;

    // Run and detach the thread
    term_flag = false;
    std::thread t(func);
    t.detach();

    // Wait until detached thread termination
    while(!term_flag)
        std::this_thread::yield();

    std::cout << "Detached Thread has terminated properly" << std::endl;

    return 0;

输出:

分离的线程已正确终止


编辑:

正如Hans Passant 提到的,您也可以使用与互斥锁关联的condition variable 来执行此操作。 这将是一个更好的解决方案(但在我的拙见中可读性较差),因为我们可以更好地控制等待的时间。

上面的基本例子可以重写为:

#include <thread>
#include <iostream>
#include <mutex>
#include <condition_variable>

int main()

    // Define the mutex and the condition variable to notify the detached thread's termination
    std::mutex m;
    std::condition_variable cv;

    // Define some function to run concurrently
    auto func = [&cv]()
        std::this_thread::sleep_for(std::chrono::seconds(2));
        cv.notify_one();
    ;

    // Run and detach the thread
    std::thread t(func);
    t.detach();

    // Wait until detached thread termination
    
        std::unique_lock<std::mutex> lk(m);
        cv.wait(lk);
    

    std::cout << "Detached Thread has terminated properly" << std::endl;

    return 0;

【讨论】:

我会尝试实现类似你的第二个代码的东西

以上是关于C++ 分离的线程可以通过哪些可能的方式发出它正在终止的信号?的主要内容,如果未能解决你的问题,请参考以下文章

无法永远分离线程c ++

有没有一种可靠的方法可以强制线程在 C++ 中停止? (尤其是分离的)

如何在 Windows C++ 上分离线程

C++笔记--Linux编程(13)-守护进程-线程

停止 MFC 线程

从分离线程停止主游戏循环的最佳方法