【问题标题】:Problem with using WINAPI threads in Qt in C++在 C++ 中的 Qt 中使用 WINAPI 线程的问题
【发布时间】:2020-08-26 22:48:34
【问题描述】:

我被分配创建一个程序来处理三个 WINAPI 线程并反映那些正在进行的条的工作流。我决定将 Qt Widgets 用于这些目的。我使用CREATE_SUSPENDED 创建标志创建处于挂起状态的线程,然后在单击按钮时使用ResumeThread 函数恢复它。当我单击它时,程序会因未处理的 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个线程功能相同,只是进度条不同。

【问题讨论】:

  • 调试器告诉你崩溃发生在哪里?此外,您的 for 循环中有错字。
  • MainWindow::ThreadFunc1staticMainWindow 的函数吗?
  • 您正在从多个线程访问相同的变量而没有任何同步(互斥锁等)。这是未定义的行为。
  • @JonathanPotter 由于分段错误导致的崩溃发生在该行的第一个线程函数中,其中设置了进度条值。此外,它在第三个函数中,直到我修正了一个错字。
  • 如果你必须显式地将函数指针转换为(LPTHREAD_START_ROUTINE),这就是问题的根源。删除 CreateThread 中的那些强制转换并显式修复线程入口点的函数签名。

标签: c++ multithreading qt winapi


【解决方案1】:

您似乎正在传递一个成员函数指针作为应该执行的函数。 请记住,如果没有“执行”函数调用的对象实例,则不能调用成员函数,静态成员函数除外。

有关解决方法,请参阅此线程:How do you use CreateThread for functions which are class members?

底线是您调用一个静态成员函数,将应该执行某些成员函数调用的对象(在本例中为您的 MainWindow 实例)传递给它,然后该实例执行调用。

编辑:

请参阅“返回值”下的 CreateThread 的 Microsoft 文档:

请注意,即使 lpStartAddress 指向数据、代码或不可访问,CreateThread 也可能成功。如果线程运行时起始地址无效,则发生异常,线程终止。由于起始地址无效而导致的线程终止被视为线程进程的错误退出。

https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createthread

【讨论】:

    【解决方案2】:

    您正在从非 ui 线程访问 ui 设备。这将导致竞争条件。为了安全地做你想做的事,你需要将 QEvents 发布到 ui 线程。或者使用QThread,信号和槽也可以达到同样的效果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-06
      • 1970-01-01
      • 1970-01-01
      • 2021-01-03
      • 1970-01-01
      • 2020-08-27
      • 1970-01-01
      相关资源
      最近更新 更多