作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个在 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/
我是一名优秀的程序员,十分优秀!