c++ - 从 std::thread 在主线程上执行回调函数

标签 c++ multithreading c++11 pthreads boost-thread

我有一个在 std::thread 退出时执行回调函数的要求,回调函数应该在主线程上执行。

在创建线程时,我需要分离线程并且不能阻止线程完成的主循环执行。

我尝试使用 std::signal 但它似乎没有在主线程上执行回调函数

#include <thread>
#include <csignal>
#include <iostream>


std::thread::id main_thread_id;

void func2()
{
    for(int i = 0; i < 10000000; i++)
    {
        // do something
    }
}

void func()
{
    for(int i = 0; i < 10; i++)
    {
        func2();
    }
    std::raise(SIGUSR1);
}

void callback(int signal)
{
    std::cout << "SIGNAL: " << signal << "      THREAD ID:" << 
    std::this_thread::get_id() << std::endl;
    bool b = std::this_thread::get_id() == main_thread_id;
    std::cout << "IS EXECUTED ON MAIN THREAD: " << b << std::endl;
}

int main()
{
    main_thread_id = std::this_thread::get_id();
    std::cout << "MAIN THREAD ID: " << std::this_thread::get_id() << std::endl;
    std::signal(SIGUSR1, callback);
    std::thread t1(func);
    t1.detach();

    for(int i = 0; i < 20; i++)
    {
        func2();
    }

    if(t1.joinable())
        t1.join();
}

我得到的结果是回调函数没有在主线程上执行。请建议我可以创建工作线程并在线程退出时在主线程上调用回调函数的方法。

感谢帮助

最佳答案

有几种方法可以做到这一点。

首先,您的主线程可能正在运行一个消息循环。在这种情况下,您将一 strip 有有效载荷的消息排队,告诉主线程运行一些代码(通过消息的指针部分携带要运行的代码到主线程,或者将其放在主线程的某个已知位置线程检查)。

第二种方法是返回类似 std::future<std::function<void()>> 的内容对象,主线程检查 future 是否准备就绪。准备就绪后,它会运行代码。

第三种方法是创建一个主线程等待的并发队列,并将您的消息(包含要运行的代码)填充到该队列中。

所有这些事情都需要主线程的积极配合。主线程不能被抢占并告诉它在没有它的配合下运行不同的代码。

哪个最好取决于您没有选择在问题中提及的程序的功能。如果你是带有消息循环的图形GUI,就用消息循环。如果您是并行化某些工作的流式处理器,并且您不需要快速执行,但最终会希望阻塞并行工作,那么 future 可能是最好的。如果您是消息传递 channel 类型的应用程序,一组队列可能是最好的。

关于c++ - 从 std::thread 在主线程上执行回调函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45333898/

相关文章:

c++ - 如何以编程方式将音频从任何录音设备路由到任何播放设备

c++ - vector 插入崩溃程序

c++ - 什么是 Visual Studio 2010 中的测试项目?

c++ - std::make_shared、std::unique_ptr 和移动构造函数

c++ - 解决 typedef u8 以使用 C++11 u8 字符串文字

c++ - amp - C++ 助手

java - 通过线程中的套接字进行对象输入/输出

多线程模式下的Java集合算法

c - C 中的行主乘法多线程

c++ - 为同一类提供不同比较运算符的最佳策略是什么?