如何在QT中使用互斥锁定线程开始轮询?

时间:2016-02-09 11:55:00

标签: c++ multithreading qt signals-slots polling

我使用的是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会话无效。

请帮忙, 亲切的问候,

2 个答案:

答案 0 :(得分:2)

使用QMutex来保护对象,就cReader的例子而言:

// class member
QMutex m_mutex;
//...

QByteArray MyClass::safeReadSomeData()
{
    m_mutex.lock();
    QByteArray result = cReader.read();
    m_mutex.unlock();

    return result;    
}

另请参阅QMutexLockerQReadWriteLock

线程之间通信和参数交换的常用和常用方法是使用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
  • 将计时器的间隔设置为20毫秒或任何您想要触发事件的间隔;间隔设置为0的计时器表示事件将尽快由其触发
  • 将计时器连接到完成工作的工作人员的插槽(检查卡是否已移除等)
  • 将对象的插槽/信号连接到用户界面的信号/插槽(使用QMutexLocker可以保护对两者的内部数据或其他QObject的访问权限(在工人居住的相同或不同的线程中)
  • 将计时器和工作人员移至QThread并启动主题

计时器将每隔X毫秒开始触发一次卡片检查。然后,工作人员将从计时器接收该信号(此处不需要互斥锁,因为计时器和工作程序具有相同的线程关联性)。工作人员会在内部发生变化,然后它会向另一个QObject或UI本身发出信号。此时互斥体会起作用,除非您在工作者所在的同一线程中访问QObject的另一个实例。

您可以通过这样做添加任意数量的线程。我有一个在后台运行6个线程的UI,访问UI和使用定时器没有任何问题。

修改 我已开始使用QTimerQThreadQObject处理small demo。应用程序不完整/错误,但您可以看到QTimer的工作原理。