<分区>
我是 C++ 和 Qt 的新手,在实现良好且不太复杂的多线程通信环境方面遇到了一些麻烦。
基本上我有 3 个线程,一个用于 GUI
,另一个用于处理通过 USB 连接到 PC 的 device
发送的更新,另一个将处理信息由 device
和 control
获取 device
和 GUI
来改变它们的状态。所以基本上有 3 个线程:GUI
、device
和 control
。
我的第一个方法是让 device
用 USB 发送的信息填充它的私有(private)成员,并有一些 get()
方法转换这些数据并返回它(使用互斥量以确保数据仍然有效)。问题是当 control
调用 device
中的 get()
方法时,它不会返回任何新内容(我原以为这些方法甚至永远不会返回因为线程被锁定在另一个方法中,但它们确实返回并且没有新信息,并且在那些 get()
方法中也没有触发断点)。
Qt通常的线程间通信方式是使用Signal和Slots,但是Signal和Slots的问题是当一个线程正在处理并且它有一个Slot时,如果发送了一些Signal,这个Slot将永远不会被执行。即使我可以设法使用 Signal 和 Slots 来触发新的数据更新,我担心会有很多信号被发送,因为设备更新非常快,而且我有很多数据类型并且使用 QAtomicInt 对许多人来说都没有用所以我的一般问题是,哪种方法是让线程共享数据并仍然继续运行无限进程循环的最佳方式?
我的目标的一个很好的例子是:
控制线程:
while(true){
angle = device.getAngle(); //device is a member of control object and is running in a separate thread
doCalculations(angle);
}
设备线程:
void process(){
while(true)
usbRead(data, size_of_data);
}
short getAngle(){
return (data[0] << 8 | data[1]);
}
我没有在这个例子中放置互斥量等,只是预期的基本功能。
这里是我开始线程的方式:
test::test(QWidget *parent) : QMainWindow(parent) , cvControl(device, 0)
{
//ui setup
connect(&device, SIGNAL(deviceConnected(bool)), this, SLOT(updateStatusConnection(bool)));
device.moveToThread(&deviceThread);
cvControl.moveToThread(&controlThread);
connect(&deviceThread, SIGNAL(started(void)), &device, SLOT(process(void)));
connect(&device, SIGNAL(deviceFinished(void)), &deviceThread, SLOT(quit(void)));
connect(&cvControl, SIGNAL(controlFinished(void)), &controlThread, SLOT(quit(void)));
connect(&deviceThread, SIGNAL(finished(void)), &device, SLOT(deleteLater(void)));
connect(&controlThread, SIGNAL(finished(void)), &cvControl, SLOT(deleteLater(void)));
connect(this, SIGNAL(startControlProcess(void)), &cvControl, SLOT(process(void)));
deviceThread.start();
controlThread.start();
}
void test::on_btnRun_clicked()
{
if(ui.btnRun->text() == "Run")
{
ui.btnRun->setText(QString("Stop"));
disbleControls();
emit startControlProcess();
}
else
{
ui.btnRun->setText(QString("Run"));
enableControls();
cvControl.abort.store(1);
}
}