这是我遇到的多线程问题。 proc需要是静态的,这意味着我看到2个线程可以通信并共享数据的唯一方法是通过全局范围。这看起来不是很干净,感觉也不是很好。我知道我可以在类中创建静态proc函数,但这仍然是静态的。
我想要做的是在类中以某种方式进行线程过程,以便ex:我可以创建一个MD5校验和类并拥有这些对象的数组,每个对象都在自己的线程上检查其哈希值,而UI线程不受此影响,另一个类可以简单地跟踪句柄并在说“完成”之前等待多个对象。这种限制通常如何克服?
答案 0 :(得分:3)
如果要在那里启动线程,则无法避免使用静态函数。但是,您可以(使用Windows)将此指针作为参数传递,并在另一侧使用它来输入类实例。
#include <windows.h>
class Threaded {
static DWORD WINAPI StaticThreadEntry(LPVOID me) {
reinterpret_cast<Threaded*>(me)->ThreadEntry();
return 0;
}
void ThreadEntry() {
// Stuff here.
}
public:
void DoSomething() {
::CreateThread(0, 0, StaticThreadEntry, this, 0, 0);
}
};
答案 1 :(得分:3)
在C ++中,Boost.Thread很好地解决了这个问题。线程由仿函数表示,这意味着(非静态)operator()
是线程的入口点。
例如,可以像这样创建一个线程:
// define the thread functor
struct MyThread {
MyThread(int& i) : i(i) {}
void operator()(){...}
private:
int& i;
};
// create the thread
int j;
boost::thread thr(MyThread(j));
通过将数据传递给线程仿函数的构造函数,我们可以将参数传递给线程,而不必依赖于全局变量。 (在这种情况下,线程被赋予对线程外部声明的整数j
的引用。)
使用其他库或API,您可以从(通常是静态的)入口点跳转到共享非静态数据。
线程函数通常采用(有时是可选的)参数(通常类型为void*
),您可以使用该参数将实例数据传递给线程。
如果你使用它来向线程传递指向某个对象的指针,那么线程可以简单地将指针强制转换回对象类型,并访问数据,而不必依赖于全局变量。
例如,(在伪代码中),这与上面的Boost示例大致相同:
void MyThreadFunc(void* params) {
int& i = *(int*)params;
...
}
int j;
CreateThread(MyThreadFunc, &j);
或者参数可以是指向您希望调用其(非静态)成员函数的对象的指针,允许您执行类成员函数而不是非成员函数。
答案 2 :(得分:0)
我不确定我理解得很好......我试一试。您在寻找thread local storage吗?
答案 3 :(得分:0)
线程创建例程通常允许您将参数传递给将在新线程中运行的函数。对于Posix pthread_create(...)和Win32 CreateThread(...)都是如此。以下是使用Pthreads的示例:
void* func (void* arg) {
queue_t* pqueue = (queue_t*)arg;
// pull messages off the queue
val = queue_pull(pqueue);
return 0;
}
int main (int argc, char* argv[]) {
pthread_t thread;
queue_t queue = queue_init();
pthread_create(&thread, 0, func, &queue);
// push messages on the queue for the thread to process
queue_push(&queue, 123);
void* ignored;
pthread_join(&thread, &ignored);
return 0;
}
任何地方都没有静电。在C ++程序中,您可以将指针传递给类的实例。