我在Windows上使用多线程c ++代码时遇到了一些麻烦。
class test
{
public:
bool flag;
test() {flag=true;}
void start_do(){while(flag) puts("doing...");}
void stop_do() {flag=0;}
}
int main()
{
test t;
HANDLE h=CreateThread(0,0,(LPTHREAD_START_ROUTINE)t.start_do,0,1,0);
Sleep(5000);
t.stop_do();
return 0;
}
我想用旗帜改变做的状态。但它不起作用。 有人可以给我一些帮助!
答案 0 :(得分:5)
整个代码没有多大意义。
首先,Windows API是一个C api。 C不知道什么是类或方法。 C只知道全局函数。所以传递成员函数是第一个错误。
其次,您提供的成员函数看起来不像CreateThread
期望的那样!你应该提供一个带有签名DWORD __stdcall (void*)
的函数,你的功能看起来根本不像。强行施放只会造成更多麻烦。
第三,传递成员函数的方法是使用sintax &ClassName::functionName
。写object.function
意味着什么。
最后,C ++有更简单的方法来创建线程,并将它们用作对象,而不是句柄:
test t;
std::thread t([&]{ t.start_do(); });
现在,我建议不要使用winapi来创建线程,除非你有充分的理由(比如指定堆栈大小,如果堆栈内存是保留还是提交等)
为了解决这里的问题,让你成功工作的方法是通过"展平"将对象转换为void*
并将其重新强制转换回某个全局函数:
DWORD __stdcall callStartDo(void* pObject){
auto object = reinterpret_cast<test*>(pObject);
if (object){
object->start_do();
}
return 0U;
}
//...
test t;
unsigned long threadID = 0U;
CreateThread(nullptr,0U,&callStartDo,&t,0,&threadID);
再次,这个例子只显示了 的方式,我强烈建议使用std::thread
。 (看看与C ++方式有多大的开销!)
答案 1 :(得分:0)
但您可以使用<thread>
。
cplusplus.com - <thread>
因为我做了,所以线程可能有点难以理解 但是如果你看一下我添加的链接就很容易了。我想。