【问题标题】:Executing a function on a specific thread in C++在 C++ 中的特定线程上执行函数
【发布时间】:2020-12-01 10:03:52
【问题描述】:

我有一个类,它的一些函数是线程安全的。

class A 
{
    public:
    // Thread Safe class B
    B foo;
    // Thread specific class C
    C bar;

    void somefunc()
    {
        // uses foo and bar
    }
}

class C
{
    public:
    C()
    {
        m_id = std::this_thread::get_id();
    }

    // id of the thread which created the class
    std::thread::id m_id;
}

A 类可以设置在不同的线程上。由于 C 类是线程特定的,我想从线程 m_id 运行 somefun

所以我想通过将 somefun 提交给 m_id 标识的线程来执行 somefun。

主要问题是,如果我知道线程的线程 ID,我能否在活动线程上运行特定函数

【问题讨论】:

  • 不是很清楚,因为C既是类型又是bar类型的变量...请给minimal reproducible example
  • 对不起,我在输入问题时搞砸了
  • 您能告诉我们您如何创建线程以及它们如何共享A 的实例吗?
  • 还是很模糊。线程安全吗?线程如何拥有A的对象?你让你的例子如此抽象以至于很难理解。更大的图景是什么?
  • thread_local C bar; 确保 bar 是线程特定的。

标签: c++ multithreading c++14


【解决方案1】:

我正在考虑通过将 somefun 提交给 m_id 标识的线程来执行 somefun。

线程通常不是这样工作的。您不能只要求任何线程停止它正在做的事情并调用某个函数。向线程提交任何东西有意义的唯一方法是,如果线程已经在运行旨在接受提交的代码,并且知道如何处理它。

您可以编写一个永远循环的线程,并在每次迭代时等待从阻塞队列中消耗std::function<...> 对象,然后调用该对象。然后,其他一些线程可以通过将std::function<...> 对象放入队列中,将它们“提交”给线程。

【讨论】:

  • 我正要编写相同的方法,但在这种情况下,使用所需的线程 ID 作为键并使用 function 作为值的 map 可能更有意义。我的感觉是,所有这些愚蠢的事情会比仅仅启动一个新线程消耗更多的时间,但这是 OP 的问题,而不是你的问题。
  • 是的,这将非常有效。你有什么想法,而不是忙着等待
  • @pr0py_s,我没有时间为此编写或查找示例,但是当客户端“提交”一个函数对象时,它可以返回一个Future 对象。 Future 对象将包含一个互斥体和一个条件变量,它会有一个名为 complete() 的方法,由工作线程调用以在提交的函数返回后发出条件信号,它会有一个名为 get() 或 @ 的方法客户端调用以等待事件的 987654329@。它还可以保存提交函数返回的值。
【解决方案2】:

您可以使用boost::asio::io_service

发布在线程上的函数(或工作)将在不同的线程上执行(在该线程上调用 io_service 的 run() 成员函数)。

一个粗略的例子:

#include <boost/asio/io_service.hpp>

boost::asio::io_service ios_;

void func(void)
{
    std::cout << "Executing work: " << std::this_thread::get_id() << std::endl;
}

// Thread 1
ios_.run();

// Thread 2
std::cout << "Posting work: " << std::this_thread::get_id() << std::endl;
ios_.post(func);

ios_.port([] () {
    std::cout << "Lambda" << std::endl;
});

【讨论】:

  • 好主意,但 OP 希望该函数由 特定 其他线程调用,而不是由碰巧可用的池工作者调用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
  • 2013-03-10
  • 1970-01-01
相关资源
最近更新 更多