如何 运行 不同的 while 循环而不破坏任何

How to run different while loops without breaking any

如何 运行 两个不同的 while 循环而不中断一个循环?

该程序通过 while 循环从 PLC(可编程逻辑控制器)收集两种不同的值。

而且这个收集应该在 同一时间 ,但是当我尝试 运行 两个循环时,它们都中断了...第一个循环就停止了返回任何值,而第二个是 运行ning.

您的程序需要连接、读取和断开两台设备,但是,它一次只能打开一个连接。因此,连接是互斥的。您可以为此使用互斥体。

您的代码建议,一个连接应该在一定的超时时间内无限期地轮询,而另一个连接则应通过按钮请求。我会简单地将两者都放在一个插槽中,一个由按钮调用,另一个由计时器调用,并用互斥锁保护它们。

大纲:

class MainProgram : QObject {
    // Other stuff
private slots:
    void on_pushCheck_clicked();
    void readPeriodically();
    
private:
    QMutex m_mutex;
    QTimer *m_timer;
};

void MainProgram::MainProgram()
{
    // other stuff

    m_timer = new QTimer(this);
    connect(m_timer, &QTimer::timeout, this, &MainProgram::readPeriodically);
    m_timer->setInterval(2000);
    m_timer->start();
}

void MainProgram::on_pushCheck_clicked()
{
    QMutexLocker l(&m_mutex);
    
    // Read from device 1
}

void MainProgram::readPeriodically()
{
    QMutexLocker l(&m_mutex);
    
    // Read from device 2
}

这是假设读取速度非常快,因为 UI 在此期间被阻塞。如果不是这种情况,您可以将读取代码放入后台工作线程。这种方法是异步的,你触发读取,一段时间后结果:

class DeviceReader : QObject {
public:
    void readDevice1();
    void readDevice2();
    
signals:
    void device1Data(int);
    void device2Data(int);
    
private:
    Q_INVOKABLE void doReadDevice1();
    Q_INVOKABLE void doReadDevice2();
    
private:
    QMutex m_mutex;
};

void DeviceReader::readDevice1()
{
    // Cross thread boundary
    QMetaObject::invokeMethod(this, "doReadDevice1", Qt::QueuedConnection);
}

void DeviceReader::doReadDevice1()
{
    QMutexLocker l(&m_mutex);
    
    // Read from device 1
    
    emit device1Data(1);
}

// similar for device 2


MainProgram::MainProgram() {
    DeviceReader *r = new DeviceReader;
    QThread *t = new QThread;
    
    r->moveToThread(t);

    // Connect signals for starting reads, or call them as necessary
    // Connect signal to deleteLater on thread when app closes
    // e.g. QApplication::aboutToQuit

    // The worker object does not have a "working" method.
    // It will just listen to events (signals) through the thread's exec loop
    t->start();
    
}