1.QThread阻塞创建线程对象的线程(一般是主线程)
class MyThread : public QThread{
Q_OBJECT
public:
MyThread(QObject *parent = NULL);
~MyThread();
protected:
void run();
};
void MyThread::run(){
qDebug( "finish!");
}
使用
MyThread thread;
thread.start();
thread.wait(); //thread是主线程创建所以这里阻塞的是主线程
当然我们先开的线程可能是要运行很久,会卡住主线程,使用QeventLoop就可以轻松解决此类问题:
MyThread thread;
thread.start();
QeventLoop;
connect(&thread,SIGNAL(finished ()),&eventLoop,SLOT(quit()));
thread.wait(1);
eventLoop.exec();
2.QMutex mutex; //使用互斥量保证对线程操作的原子性
mutex.lock();
//业务代码
mutex.unlock();
QWaitCondition是用来同步线程的条件变量
/*mutex将被解锁,并且调用线程将会阻塞,直到下列条件之一满足才想来:
(1)另一个线程使用wakeOne()或wakeAll()传输给它;
(2)time毫秒过去。*/
wait ( QMutex * mutex, unsigned long time = ULONG_MAX )
/**唤醒所有等待的线程,线程唤醒的顺序不确定,由操作系统的调度策略决定***/
wakeAll ()
/**唤醒等待QWaitCondition的线程中的一个线程,线程唤醒的顺序不确定,由操作系统的调度策略决定**/
wakeOne()
//例子:
全局配置
const int DataSize = 127;
const int BufferSize = 8192;
char buffer[BufferSize];
QWaitCondition bufferNotEmpty;
QWaitCondition bufferNotFull;
QMutex mutex;
int numUsedBytes = 0;
//生产
class Producer : public QThread
{
public:
Producer(QObject *parent = NULL) : QThread(parent)
{
}
void run() override
{
for (int i = 0; i < DataSize; ++i) {
mutex.lock();
if (numUsedBytes == BufferSize)
bufferNotFull.wait(&mutex);
mutex.unlock();
buffer[i % BufferSize] = i;//"ACGT"[QRandomGenerator::global()->bounded(4)];
mutex.lock();
++numUsedBytes;
bufferNotEmpty.wakeAll();
mutex.unlock();
}
}
};
//消费
class Consumer : public QThread
{
Q_OBJECT
public:
Consumer(QObject *parent = NULL) : QThread(parent)
{
}
void run() override
{
for (int i = 0; i < DataSize; ++i) {
mutex.lock();
if (numUsedBytes == 0)
bufferNotEmpty.wait(&mutex);
mutex.unlock();
fprintf(stderr, "%d\n", buffer[i % BufferSize]);
mutex.lock();
--numUsedBytes;
bufferNotFull.wakeAll();
mutex.unlock();
}
fprintf(stderr, "\n");
}
signals:
void stringConsumed(const QString &text);
};
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
Producer producer;
Consumer consumer;
producer.start();
consumer.start();
producer.wait();
consumer.wait();
return 0;