我被指派创建一个程序,处理三个WINAPI线程,并在进度条中反映这些线程的工作流程。我决定使用Qt Widgets来实现这些目的。我在暂停状态下创建这些线程,使用 CREATE_SUSPENDED
创建标志,然后我用 ResumeThread
函数,当我点击该按钮时,程序以未处理的异常win32崩溃。当我点击它时,程序以一个未处理的异常win32崩溃。为什么会发生这种情况?
我的 "创建 "按钮点击槽
void MainWindow::on_pb_create_clicked()
{
hThread[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadFunc1, NULL, CREATE_SUSPENDED, &thID[0]);
hThread[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadFunc2, NULL, CREATE_SUSPENDED, &thID[1]);
hThread[2] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadFunc3, NULL, CREATE_SUSPENDED, &thID[2]);
threadsCreated = true;
}
我的 "开始 "按钮点击槽
void MainWindow::on_pb_start_clicked()
{
if(threadsCreated)
{
for(int i = 0; i = 2; i++)
{
ResumeThread(hThread[i]);
}
}
else
{
QMessageBox msg;
msg.setWindowTitle("Error");
msg.setText("Threads are not created");
msg.exec();
}
}
我的线程功能
DWORD WINAPI MainWindow::ThreadFunc1(LPVOID lpParams)
{
for(int i = 0; i < 100; i++)
{
ui->progressBar->setValue(i);
sleep(500);
}
return 0;
}
其他2个线程功能是一样的,只是使用的进度条不同。
你正在从一个非ui线程访问ui设备。这将导致一个竞赛条件。为了安全地完成你的任务,你需要将QEvents发布到ui线程中。或者使用QThread,信号和插槽也可以达到同样的目的。
似乎你传递了一个成员函数指针作为应该被执行的函数,请记住,除了静态成员函数外,如果没有 "执行 "函数调用的对象实例,你不能调用成员函数。
请看这个线程的变通方法。如何为类成员函数使用CreateThread?
底线是你调用一个静态成员函数,把应该执行某个成员函数调用的对象传递给它(你的 MainWindow
在这种情况下),然后该实例执行调用。
编辑。
参见微软文档中 "返回值 "下的CreateThread。
注意,即使lpStartAddress指向数据、代码或不可访问,CreateThread也可能成功。如果线程运行时启动地址无效,则会发生异常,线程终止。因无效的启动地址而导致的线程终止会被处理为线程的进程错误退出。
https:/docs.microsoft.comen-uswindowswin32apiprocessthreadsapinf-processthreadsapi-createthread