我使用的是Ubuntu 12.04和Qt版本4.8.3。 在Qt主窗口中,我设法打开我的设备,这部分代码正在运行。 现在我打开设备后,如果有卡,我需要等待。这意味着我必须使用轮询来从卡中获取数据。但轮询必须是无限循环。轮询卡到达和删除。
每20毫秒卡到达的示例轮询,当检测到卡时,我需要每隔20毫秒切换轮询以进行卡片移除。因此,当检测到卡到达或移除时,我的应用程序发出Qt事件信号,以便另一个Qt线程现在可以继续读/写卡。
我读到有关QThread,互斥锁等等,我有点困惑。 我有一个主窗口和一个工人阶级。在我的主窗口中,我编码为;
// Open a reader (from my SDK)
cReader.open
//If the reader is open use;
thread = new QThread();
worker = new Worker();
worker->moveToThread(thread);
connect(worker,SIGNAL(??????),SLOT(?????);
connect(worker,SIGNAL(?????),SLOT(?????);
.........
首先我必须使用connect for SIGNAL / SLOT并开始卡到达/删除轮询。如果检测到任何卡,我有信号到另一个线程从卡读取或写入卡。
所以我不知道从哪里开始或如何拨打信号/插槽?我需要帮助来填补??????高于SIGNAL / SLOT。
编辑:我还需要轮询线程和卡片处理线程共享的互斥锁。这是因为如果打开,卡片轮询命令将使我的mifare会话无效。
请帮忙, 亲切的问候,
答案 0 :(得分:2)
使用QMutex
来保护对象,就cReader的例子而言:
// class member
QMutex m_mutex;
//...
QByteArray MyClass::safeReadSomeData()
{
m_mutex.lock();
QByteArray result = cReader.read();
m_mutex.unlock();
return result;
}
另请参阅QMutexLocker,QReadWriteLock。
线程之间通信和参数交换的常用和常用方法是使用signals & slots。例如:
thread = new QThread();
worker = new Worker();
worker->moveToThread(thread);
connect( thread, SIGNAL(started()), worker, SLOT(startMyWork()) );
connect( worker, SIGNAL(sigCardDetected()), someOtherObject, SLOT(onCardDetected()) );
thread->start();
//...
官方文档中的有用文章:Threads and QObjects
此外,我认为关于 QThread
的回答对您有用:https://stackoverflow.com/a/35056527/4149835
P.S。您确定需要使用两个不同的附加线程来检测和读/写吗?
答案 1 :(得分:1)
它不是线程安全的(除非一个QObject
访问另一个QObject
中的数据并且两者都属于同一个线程。)
就互斥锁的使用而言,QMutexLocker
是您的朋友,我建议您使用它而不是手动处理锁定/解锁。
如果你重新阅读你的问题,你会注意到你大量使用间隔。我们如何处理间隔?使用QTimer
。这是我的建议:
QTimer
QObject
QMutexLocker
可以保护对两者的内部数据或其他QObject
的访问权限(在工人居住的相同或不同的线程中)QThread
并启动主题计时器将每隔X毫秒开始触发一次卡片检查。然后,工作人员将从计时器接收该信号(此处不需要互斥锁,因为计时器和工作程序具有相同的线程关联性)。工作人员会在内部发生变化,然后它会向另一个QObject
或UI本身发出信号。此时互斥体会起作用,除非您在工作者所在的同一线程中访问QObject
的另一个实例。
您可以通过这样做添加任意数量的线程。我有一个在后台运行6个线程的UI,访问UI和使用定时器没有任何问题。
修改强>
我已开始使用QTimer
,QThread
和QObject
处理small demo。应用程序不完整/错误,但您可以看到QTimer
的工作原理。