当前位置: 首页 > 知识库问答 >
问题:

从std::thread对主线程执行回调函数

楚乐逸
2023-03-14

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

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

我尝试使用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();
}

共有1个答案

连俊智
2023-03-14

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

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

第二种方法是返回一个std::future > 对象,主线程检查future是否准备好了。当它准备就绪时,它运行代码。

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

这些都需要主线的积极配合。主线程不能在没有其合作的情况下被预先设置并被告知运行不同的代码。

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

 类似资料:
  • 问题内容: 我有一个处理来自.NET Remoting的异步回调的Python脚本。这些回调在虚拟(工作)线程中执行。从我的回调处理程序内部,我需要调用在脚本中定义的函数,但需要在主线程中执行该函数。 主线程是将命令发送到服务器的远程客户端。其中一些命令会导致异步回调。 基本上,我需要等效于.NET的Invoke方法。这可能吗? 问题答案: 您想使用Queue(现在是python 3的队列)类来设

  • 我确信这两个列表都不是空的,并且正在调用,但是没有调用order execution run方法....

  • 线程(译注:大约是C++11中最激动人心的特性了)是一种对程序中的执行或者计算的表述。跟许多现代计算一样,C++11中的线程之间能够共享地址空间。从这点上来看,它不同于进程:进程一般不会直接跟其它进程共享数据。在过去,C++针对不同的硬件和操作系统有着不同的线程实现版本。如今,C++将线程加入到了标准件库中:一个标准线程ABI。 许多大部头书籍以及成千上万的论文都曾涉及到并发、并行以及线程。在这一

  • Core Java提供对多线程程序的完全控制。 您可以开发一个多线程程序,可以根据您的要求完全暂停,恢复或停止。 您可以在线程对象上使用各种静态方法来控制它们的行为。 下表列出了这些方法 - Sr.No. 方法和描述 1 public void suspend() 此方法将线程置于挂起状态,并可以使用resume()方法恢复。 2 public void stop() 此方法完全停止线程。 3 p

  • 本文向大家介绍iOS 在主线程上执行,包括了iOS 在主线程上执行的使用技巧和注意事项,需要的朋友参考一下 示例 当异步执行任务时,通常需要确保在主线程上运行一段代码。例如,您可能要异步访问REST API,但将结果放在屏幕上的UILabel中。在更新UILabel之前,必须确保您的代码在主线程上运行: 每当您更新屏幕上的视图时,请始终确保您正在主线程上执行此操作,否则可能会发生未定义的行为。

  • 我是spring batch的新手。我已经使用多个线程从spring创建并成功执行了作业,它工作得很好,只是当程序执行完成时,程序流不会结束/停止。i、 即使main方法的最后一条语句被执行,程序也不会退出。我不确定它是否一直在等待线程完成,或者是什么。有人能给我一些建议吗?“下面是我的作业配置文件 下面是启动器代码 如上所述,代码在5个不同的线程中为任务“hello”运行,为任务“world”运