非常好的博文:Qt 线程基础(QThread、QtConcurrent等) http://blog.csdn.net/dbzhang800/article/details/6554104
QThread 是用来管理线程的,它所处的线程和它管理的线程并不是同一个东西
QThread 所处的线程,就是执行 QThread t(0) 或 QThread * t=new QThread(0) 的线程。也就是咱们这儿的主线程
QThread 管理的线程,就是 run 启动的线程。也就是次线程
因为QThread的对象在主线程中,所以他的slot函数会在主线程中执行,而不是次线程。除非:QThread 对象在次线程中
Thread(QObject* parent=0):QThread(parent) { //moveToThread(this); }
多线程同步
Qt提供了以下几个用于同步的类:QMutex、QReadWriteLock、QSemaphore和QWaitCondition。QMutex类提供了一种保护一个变量或者一段代码的方法,这样就可以每次只让一个线程读取它。这个类提供里一个lock()函数来锁住互斥量(mutex)。另外,QMutex类还提供了一个tryLock()函数,如果该互斥量已经锁住,它就会立即返回。
void Thread::run() { /* while(!stopped) std::cerr<<qPrintable(messageStr); stopped=false; std::cerr<<std::endl; */ forever{ mutex.lock(); if(stopped) { stopped=false; mutex.unlock(); break; } mutex.unlock(); std::cerr<<qPrintable(messageStr); } std::cerr<<std::endl } void Thread::stop() { mutex.lock() stopped=true; mutex.unlock(); } 使用QMutexLock可以简化QMutex, void Thread::run() { forever{ QMutexLocker locker(&mutex); if(stopped) { stopped=false; mutex.unlock(); break; } mutex.unlock(); std::cerr<<qPrintable(messageStr); } std::cerr<<std::endl; } void Thread::stop() { QMutexLocker locker(&mutex); // mutex.lock(); stopped=true; // mutex.unlock(); }
共享琐:QReadWriteLock
MyData data;QReadWriteLock lock;void ReadThread::run(){ ... lock.lockForRead(); access_data_without_modify(&data); lock.unlock(); ...}
void ReadThread::run()
{ ... lock.lockForWrite();
modify(&data);
lock.unlock();
...
}
QT--QSocketNotifier类介绍http://blog.csdn.net/qustdjx/article/details/7649508
下面将说明如何使用 QSocketNotifier 来监听串口数据:
在使用 open 方法打开串口并设置好属性后,可以使用 Qt 的类 QSocketNotifier 来监听串口是否有数据可读,它是事件驱动的, 配合 Qt 的 signal/slot 机制,当有数据可读时,QSocketNotifier 就会发射ativated 信号,你只需要创建一个 slot 连接到该信号即可,代码如下所示:
m_fd = openSerialPort();
if (m_fd < 0){
QMessageBox::warning(this, tr("Error"), tr("Fail to open serial port!"));
return ;
}
m_notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
connect (m_notifier, SIGNAL(activated(int)), this, SLOT(remoteDataIncoming()));
在上述代码中,我们首先使用上面封装的 openSerialPort 函数打开串口并配置串口属性,接着我们用 m_fd 和 QSocketNotifier::Read 作为参数构造了一个 QSocketNotifier 的实例,QSocketNotifier::Read 参数表示我们需要关心串口的可读状态,最后将 QSocketNotifier 实例的activated 信号连接到 remoteDataIncoming slot,当有数据可读时,remoteDataIncoming slot 会被调用。