简体   繁体   English

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

[英]How do I start polling with mutex locked thread in QT?

I am using Ubuntu 12.04 with Qt version 4.8.3. 我正在使用Qt版本4.8.3的Ubuntu 12.04。 In Qt main window I manage to open my devices and this part of the code is working. 在Qt主窗口中,我设法打开设备,这部分代码正在运行。 Now after I open devices I need to wait if a card is present. 现在,在打开设备后,我需要等待是否有卡。 It means I have to use polling to get the data from card. 这意味着我必须使用轮询从卡中获取数据。 But the polling must be infinite loop. 但是轮询必须是无限循环的。 Polling for card arrival and removal. 轮询卡的到达和取出。

Example poll for card arrival every 20ms and when a card is detected I need to switch poll for card removal every 20 ms. 每20毫秒一次到达卡的轮询示例,当检测到卡时,我需要每20毫秒切换一次轮询以取出卡。 So when a card arrival or removal is detected, my app signals Qt event such that another Qt thread can now proceed to read/write the card. 因此,当检测到卡到达或取出时,我的应用会发出Qt事件信号,以便另一个Qt线程现在可以继续读取/写入卡。

I read about QThread, mutex locked so on and I am bit confused. 我读到有关QThread,互斥锁被锁定等信息,我有点困惑。 I have a main window plus a worker class. 我有一个主窗口和一个工人班。 In my mainwindow I code as; 在我的主窗口中,我编码为:

// 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(?????);
.........

First I must use connect for SIGNAL/SLOT and start the card arrival/removal polling. 首先,我必须使用connect进行SIGNAL / SLOT并开始卡到达/移除轮询。 Than if any card detected I have signal to another thread to read from card or write into the card. 比起检测到任何卡,我有信号通知另一个线程从卡中读取或写入卡中。

So I don't know where to start or how to call signal/slot? 所以我不知道从哪里开始或如何调用信号/插槽? I need help to fill the ?????? 我需要帮助来填补?????? above SIGNAL/SLOT. 高于信号/插槽。

Edited: I also need mutex lock shared by the polling thread and the card handiling thread. 编辑:我还需要由轮询线程和卡处理线程共享的互斥锁。 This is because a card poll command will invalidate my mifare session if opened. 这是因为打开卡查询命令会使我的mifare会话无效。

Any help please, Kind Regards, 如有任何帮助,

Using QMutex for protection an object, on the example of your cReader: QMutex的示例中,使用QMutex保护对象:

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

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

    return result;    
}

See also QMutexLocker , QReadWriteLock . 另请参见QMutexLockerQReadWriteLock

Common and usual way for communication and parameters exchange between threads is using signals & slots . 线程之间的通信和参数交换的常用方法是使用信号和插槽 Example: 例:

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();
//...

Useful article from official documentation: Threads and QObjects 官方文档中的有用文章: 线程和QObjects

Also I think this answer about QThread will be useful for you: https://stackoverflow.com/a/35056527/4149835 我也认为有关QThread答案将对您有用: https : //stackoverflow.com/a/35056527/4149835

ps Are you sure that you need to use two different additional threads for detecting and reading/writing? ps是否确定需要使用两个不同的附加线程进行检测和读取/写入?

It is not thread-safe (unless one QObject accesses data in another QObject and both belong to the same thread). 它不是线程安全的(除非一个QObject访问另一个QObject数据并且它们都属于同一线程)。

In terms of usage of mutexes the QMutexLocker is your friend and I advise you to use it instead of manually handling the locking/unlocking. 就互斥锁的使用而言, QMutexLocker是您的朋友,我建议您使用它而不是手动处理锁定/解锁。

If you re-read your question you will notice that you heavily use intervals. 如果重新阅读您的问题,您会发现自己大量使用间隔。 And how do we handle intervals? 以及我们如何处理间隔? Using QTimer . 使用QTimer Here is my suggestion: 这是我的建议:

  • Create a QTimer along with the worker QObject 与工作程序QObject一起创建QTimer
  • Set the interval of the timer to 20ms or whatever interval you want for it to tigger an event; 将计时器的间隔设置为20ms或您希望其触发事件的任何间隔; a timer with interval set to 0 means that an event will be triggered by it as soon as possible 时间间隔设置为0的计时器表示将尽快触发一个事件
  • Connect the timer to the slot of the worker that does the work (check if card is removed etc.) 将计时器连接到工作人员的插槽上(检查卡是否已取出等)
  • Connect the object's slots/signals to the signals/slots of your UI (using QMutexLocker will enable you to secure the access on the internal data of both) or another QObject (in the same or a different thread where the worker is residing) 将对象的插槽/信号连接到UI的信号/插槽(使用QMutexLocker将使您能够保护对两者的内部数据的访问)或另一个QObject (在工人所在的相同或不同线程中)
  • Move both the timer and worker to a QThread and start the thread 将计时器和工作器都移至QThread并启动线程

The timer will start triggering a check for your card every X milliseconds. 计时器将开始每X毫秒触发一次对您卡的检查。 The worker will then receive that signal from the timer (here no mutex is required since both the timer and the worker are with the same thread-affinity). 然后,工作程序将从计时器接收该信号(此处不需要互斥,因为计时器和工作程序都具有相同的线程亲和力)。 Things will change internally for the worker and then it will emit a signal to another QObject or the UI itself. 事情将在内部为工作人员更改,然后它将向另一个QObject或UI本身发出信号。 At this point the mutexes come into play unless you are accessing another instance of a QObject in the same thread where your worker is. 此时,除非您在工作线程所在的同一线程中访问QObject另一个实例,否则互斥锁才起作用。

You can add as many threads as you like by doing so. 您可以根据需要添加任意多个线程。 I have a UI that has 6 threads running in the background accessing both the UI and each other without any problem using timers. 我有一个UI,该UI具有6个在后台运行的线程,可以同时访问UI和彼此,而使用计时器没有任何问题。

EDIT: I have started working on a small demo using QTimer , QThread and QObject . 编辑:我已经开始使用QTimerQThreadQObject进行小型演示 Application is incomplete/buggy but you can see how QTimer works. 应用程序不完整/混乱,但是您可以看到QTimer工作方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM