Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 互斥在Qt阻塞主示例中的使用_C++_Multithreading_Qt_Serial Communication - Fatal编程技术网

C++ 互斥在Qt阻塞主示例中的使用

C++ 互斥在Qt阻塞主示例中的使用,c++,multithreading,qt,serial-communication,C++,Multithreading,Qt,Serial Communication,我正在学习如何使用Qt进行串行通信。在本例中,串行通信是以同步方式完成的,因此,为了保持GUI的响应性,将创建一个单独的(非GUI)线程来处理串行通信。我不理解的是,在负责通信的线程(即主线程)中使用互斥体来同步线程的部分: 注意,在主线程中调用了transaction()方法,但是 请求在主线程中提供。主线程数据 成员在不同线程中同时读写,因此 QMutex类用于同步访问 void MasterThread::transaction(const QString &portName, i

我正在学习如何使用Qt进行串行通信。在本例中,串行通信是以同步方式完成的,因此,为了保持GUI的响应性,将创建一个单独的(非GUI)线程来处理串行通信。我不理解的是,在负责通信的线程(即
主线程
)中使用互斥体来同步线程的部分:

注意,在主线程中调用了transaction()方法,但是 请求在主线程中提供。主线程数据 成员在不同线程中同时读写,因此 QMutex类用于同步访问

void MasterThread::transaction(const QString &portName, int waitTimeout, const QString &request)
{
    QMutexLocker locker(&mutex);
    this->portName = portName;
    this->waitTimeout = waitTimeout;
    this->request = request;
    if (!isRunning())
        start();
    else
        cond.wakeOne();
}
[主线程运行方法]

void MasterThread::run()
{
    bool currentPortNameChanged = false;

    mutex.lock();
QString currentPortName;
if (currentPortName != portName) {
    currentPortName = portName;
    currentPortNameChanged = true;
}

int currentWaitTimeout = waitTimeout;
QString currentRequest = request;
mutex.unlock();
在任何情况下都不应调用transaction()方法 与获取数据的进程同时进行。注意,当 QString类是可重入的,它不是线程安全的。因此,事实并非如此 建议读取请求线程中的串行端口名称,以及 超时或请求另一个线程中的数据。MasterThread类可以 一次只处理一个请求

我的问题是:

  • 我不明白互斥的必要性。我的推理是,只有一个线程(在
    对话框
    类中创建)处理通信,因此没有竞争条件,也不需要同步

  • 我对上面引用的最后一句话感到更困惑(即“在任何情况下……”)。“另一个获取数据的进程”是什么意思?我们这里不是只有一个进程(即整个应用程序)和两个线程(一个用于GUI,一个用于串行通信)并且这两个线程没有共享数据吗?为什么
    QString
    的线程安全性在这里很重要

  • 我不明白互斥的必要性。我的推理是,只有一个线程(在Dialog类中创建)处理通信,因此没有竞争条件,也不需要同步

    应用程序启动时已有一个线程处于活动状态。这就是gui线程。一旦启动其他线程,就会有多个线程。如果通信线程与其他线程隔离,那么它将是无用的。一旦不再隔离,就需要一种同步访问共享数据的方法,并且一些数据必须共享——这就是没有隔离的定义。解除线程隔离的唯一方法是共享一些数据(如果没有使用操作系统或硬件可能提供的低级消息传递功能,这里就没有)

    同步在gui线程和通信线程之间进行。
    transaction()
    方法必须是线程安全的,即它必须使用一些同步原语-这里是互斥体

    “另一个获取数据的进程”是什么意思

    在特定的句子中,进程被用作线程的一个不幸的同义词

    为什么QString的线程安全性在这里很重要

    QString
    的线程安全很重要,因为一次只能从一个线程访问特定的
    QString
    实例,即不支持并发。甚至不支持读并发——有些人认为,仅仅因为他们不修改数据,只读访问是线程安全的。除非明确规定,否则不会。具体来说,在本例中:在线程1中读取给定的
    QString
    ,在线程2中写入,会导致未定义的行为,这不是假设。你会弄坏东西的

    这两个线程没有共享数据


    一个进程的线程都在相同的地址空间中,因此默认情况下共享数据。因此,需要同步原语。同步可能是隐式的,例如,如果线程通过发布事件进行通信,则事件队列是同步原语:它序列化从事件海报到事件接收者的访问,即,将针对给定线程的事件海报同步到该线程中的接收者。

    谢谢您的回答。还有一件事让我更加清楚,那就是我认为
    事务
    方法是在
    主线程
    线程中执行的,这是错误的,因为它是在主线程中执行的。这正是你提到的解除隔离的地方。