【问题标题】:c++ running code on secondary std threadc++ 在辅助 std 线程上运行代码
【发布时间】:2014-01-10 20:58:26
【问题描述】:

我在谷歌上搜索了 2 多个小时,但我找不到我的问题的答案:

我在 Windows 8 (x86) 上使用 C++(Visual Studio Express 2012)

我想在进程的主线程上从我的工作人员 std::thread 运行一个方法。我尝试使用它们的 std::thread::id 创建两个线程的引用,然后交换它们,但我无法创建引用。

从我的辅助线程调用以下方法:

[..]

void run(bool *running, thread::id _mainThreadId)
{
   while(*running)
   {  
        thread mainThread(_mainThreadId);
        thread thisThread(this_thread::get_id());
        thisThread.swap(mainThread);
        //mainThreads work:
        [..]
        thisThread.swap(mainThread);
        //thisThread again
   }
}

但是当我尝试编译我的项目时,出现了一个错误,显示构造函数 thread(thread::id) 不存在。

我的问题:

有没有更好的方法在另一个线程上运行代码? 有没有办法使用它的 id 来获取对线程的引用?

提前致谢!

PS: 如有语法错误,请见谅。我来自德国。 :)

【问题讨论】:

    标签: c++ multithreading visual-studio-2012 windows-8 std


    【解决方案1】:

    每个线程就像一个顺序运行的程序,不能随意让它跳转到程序的其他部分。

    您的要求相当于启动另一个线程,可能会暂停原来的线程直到它完成,然后让这个新线程执行您想要的操作。这是因为每个线程都有一个指令指针,告诉它它在哪里。每个线程也有寄存器和堆栈等。如果你想让一个线程做一些不同的事情,你必须保存所有这些状态,做你的事情,然后恢复所有状态。这相当于只是创建了一个新线程(操作系统将为您保存所有状态)。

    也许值得问一下为什么要在另一个线程中运行一个方法。做你所要求的唯一方法是向另一个线程发送一条消息,说“请使用这些参数运行这个方法并给我结果”,但这通常是没有意义的。如果您需要其他线程拥有的某种权限,应该可以要求操作系统授予您的线程这些权限。

    【讨论】:

    • 好的,谢谢。我认为它会是这样的,但在 java 中你可以轻松地将代码发布到主线程,所以我认为这在 c++ 中也是可能的:)
    • @user3183356 我不确定您指的是什么。据我所知,您唯一的选择是在 Java 中启动一个新线程,与 C++ 相同。您能否提供有关您正在谈论的内容的资源?
    • 对不起,我的意思是 Android 的 Activity 类 (runOnUiThread)。自从我上次使用它已经有一段时间了。
    • 啊,好吧,那你说的是特定框架中的东西。 UI 有点特殊,因为您有时需要在 UI 线程上执行操作以确保一致性。这几乎可以肯定是通过向 UI 发送描述您想要的调用的信息并要求它执行操作来实现的。 UI 有某种任务队列,当它可以处理它时,它会运行您的代码(重要的部分是它不一定会立即执行)。据我所知,任务队列没有标准的 C++ 构造。
    【解决方案2】:

    我实际上并没有得到你正在做的交换。如果您的意图是将执行推迟到不同的线程,那不是它的完成方式:

    您需要在创建线程时传递一个指向函数的指针。该函数将在单独的线程中执行。如果你想等待它,你 join 到线程。您检查过thread 文档中的示例吗?

    【讨论】:

      【解决方案3】:

      如果您想在另一个线程上运行某些东西,您需要将一些信息传达给该另一个线程以通知另一个线程。您不能“交换”线程,希望某些东西正在另一个线程上运行!

      一种方法是为您的线程设置消息队列,您将在其中发送作业,每个线程只是查看其消息队列并处理来自该队列的任何内容,例如:

      int main() {
          SomeThreadEnabledQueue<std::function<bool()>> mainQueue;
          // kick of other threads possibly passing a pointer to the queue, etc.
      
          for (bool done(false); !done; ) {
              std::function<bool()> job = mainQueue.pop();
              done = job();
          }
      
          // join other threads, etc.
       }
      

      然后,您的其他线程将通过向mainQueue() 添加合适的消息向您的线程发送合适的消息:

      void run(std::atomic<bool> *running,
               SomeThreadEnabledQueue<std::function<bool()>>* queue) {
         while(*running)
         {
             // do whatever
             queue->push([=](){ /* what the other thread should do... */; return false; });
             // if necessary for the work to be completed, transfer a future and wait on it
         }
      }
      

      上述方法当然适用于在特定线程上执行特定工作项。不过,是否必须在特定线程上执行某些东西是一个好主意是一个不同的问题。通常,最好有一个线程池并确保某些对象一次最多只能由一个线程运行。

      请注意,我更改了 running 参数,该参数似乎是指向 bool 的指针,该指针在另一个线程中更改为 std::atomic&lt;bool&gt;:读取另一个线程中正在更改的值而不同步会产生数据竞争,并且,因此,未定义的行为。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多