如何在C++中的特定线程id上执行函数



在给定线程ID的情况下,我是否可以在特定线程上调用函数?我现在在另一个线程上。

您需要来自目标线程的合作;例如,目标线程必须执行一个循环,在循环的顶部等待某种消息框。通过该消息框,您可以向它提供一条消息,其中包含要调用的函数和要使用的参数。通过相同的机制,函数可以生成包含调用结果的回复。

但是你不能让一个运行任意代码的随机线程调用你的函数。尽管,永远不要说永远。有一些技巧,比如异步POSIX信号等等:向线程发送一个信号,线程检查一些数据,告诉它调用一个函数。这被信号处理程序可以安全完成的限制所混淆。

在调试器中,您可以停止所有线程,然后"切换"到特定线程,并在其上下文中计算表达式,包括函数调用。这也是一种不适合集成到生产代码中的方法;您不知道停止的线程处于什么状态才能安全可靠地在该线程中执行任何操作。

一种可能的解决方案是使工作线程基于任务(函数(执行,即使用容器存储希望工作线程执行的函数,而工作线程的工作是在容器中执行函数。

这里有一个例子,希望能有所帮助。

#include <iostream>
#include <list>
#include <functional>
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>
using namespace std;
void foo() {
cout << "foo() is called" << endl;
}
template<typename T>
class TaskQueue {
public:
void enqueue(T&& task) {
unique_lock<mutex> l(m);
tasks.push_back(move(task));
cv.notify_one();
}
bool empty() { unique_lock<mutex> l(m); return tasks.empty(); }
void setStop() { stop = true; unique_lock<mutex> l(m); cv.notify_one(); }
void run() {
T t;
while (!stop) {
{
unique_lock<mutex> l(m);
cv.wait(l, [&] {return !tasks.empty() || stop;});
if (!tasks.empty()) {
t = move(tasks.front());
tasks.pop_front();
}
else 
return;
}
t();
}
}
private:
atomic<bool> stop = false;
mutex m;
condition_variable cv;
list<T> tasks;
};
int main() {
TaskQueue<function<void(void)>> taskq;
thread t(&TaskQueue<function<void(void)>>::run, &taskq);
taskq.enqueue(foo);
taskq.enqueue(foo);
taskq.enqueue(foo);
while (!taskq.empty()) {}
taskq.setStop();
t.join();
}

最新更新