【问题标题】:Problems Calling a Thread from another GUI Thread in QT从 QT 中的另一个 GUI 线程调用线程的问题
【发布时间】:2016-10-31 20:14:53
【问题描述】:

我正在使用 QT 运行交通项目。 有一次,我创建了一个线程,该线程必须设置一些变量,等待某个时间,将变量设置为另一个值并死掉; 在该线程等待时,其他线程必须继续运行。 这是线程类

//CLASS FOR CHANGING DYNAMIC LANE
class change_lane : public QThread
{
private:
    lane* dynamic_lane;
    lane_marking *lm_A;
    lane_marking *lm_B;
    time_t change_time;
    direction_way new_dir;
public:
    change_lane(lane *dl, time_t ct, direction_way new_dir) :
        dynamic_lane(dl), lm_A(dl->get_mark_A()), lm_B(dl->get_mark_B()), change_time(ct), new_dir(new_dir) {}
    void run()
    {
        QMutex mux;
        mux.lock();
        cout << "CHANGING DYNAMIC LANE" << endl;
        switch(new_dir)
        {
        case A:
            lm_A->change_status(changing_sw);
            lm_B->change_status(changing_df);
            break;
        case B:
            lm_A->change_status(changing_df);
            lm_B->change_status(changing_sw);
            break;
        }
        sleep(change_time);
        switch(new_dir)
        {
        case A:
            lm_A->change_status(same_way);
            lm_B->change_status(different_way);
            break;
        case B:
            lm_A->change_status(different_way);
            lm_B->change_status(same_way);
            break;
        }
        dynamic_lane->setDirection(new_dir);
        cout << "DONE: CHANGING DYNAMIC LANE" << endl;
        mux.unlock();
    }
};

这就是我调用线程的方式;

这是在另一个运行在 while(true) 循环中的线程内;

线程只被调用一次,因为它将 w->changeing_lane 设置为 false;

//CHECKING IF DYNAMIC ROAD MUST CHANGE
    if(w->changing_lane == true)
    {
        direction_way temp_dirway = w->dyn_lane->getDirection();

         switch(temp_dirway)
         {
             case (A):
             {
                 change_lane cl_A(w->dyn_lane,5,B);
                 cl_A.start();
                 break;
             }
             case (B):
             {
                 change_lane cl_B(w->dyn_lane,5,A);
                 cl_B.start();
                 break;
             }
         }
        w->changing_lane = false;
    }

当我按下按钮时,我收到此错误:

程序停止响应。

在应用程序输出中,我收到此错误:

QThread:在线程仍在运行时被销毁 QMutex:正在销毁 QThread::setTerminationEnabled() 中锁定的互斥锁 ASSERT 失败: “当前线程不是用 QThread 启动的。”,文件 线程\qthread_win.cpp,第 641 行

请帮忙

【问题讨论】:

  • 您在您的run 函数inside 中声明了一个互斥锁,该互斥锁随后被锁定并且永远不会提供给其他人。因此,实际上没有其他人在使用该互斥体。这让我的脑海里敲响了各种各样的警钟。
  • 我用 QMutex 试过了,没用,同样的问题!
  • 也许您应该在 if 语句(甚至是 while 循环)之外的某处实例化 cl_A 和 cl_B。但是,这意味着您将无法将参数 A、B 传递给构造函数,因此您必须定义另一个类方法来执行此操作
  • QThread 不是线程,而是线程控制器。因此,从 QThread 继承并不是使用它的最佳方式,除非您想更改 Qt 处理线程的方式。 here 描述了使用 QThread 的更好方法。此外,如果 lane_marking 派生自 QObject,那么将 change_status 更改为插槽并发出信号以调用该函数将消除对 QMutex 的需求。
  • 您将从 Maya Posch 的 How To Really, Truly Use QThreads 中受益。子类化 QThread 几乎总是错误的做法。

标签: c++ multithreading qt


【解决方案1】:

父线程通过QThread对象控制子线程。因此QThread对象的生命周期应该大于线程的生命周期。启动线程后,您应该等待线程完成后再删除它。调用 QThread::wait() 来执行此操作。

您在线程中声明的互斥锁不会做任何事情,因为它是线程本地的。互斥锁的意义在于在不同的线程中使用它来保护它们之间共享的数据(因此互斥锁必须可供多个线程访问才能使用)。

【讨论】:

    猜你喜欢
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-11
    • 1970-01-01
    • 1970-01-01
    • 2014-02-13
    相关资源
    最近更新 更多