Qt中线程安全的类有QMutex,QMutexLocker,QReadWriteLock,QReadLocker,QWriteLocker,QSemaphore(信号量),QThreadStorage<T>,QWaitCondition
#include<iostream>
#include<QThread>
#include<QMutex>
#include<QWaitCondition>
using namespace std;
QMutex mutex;
QWaitCondition wait1;
class Thread1:public QThread{
public:
void run(){
mutex.lock();
for(int i=0;i<5;i++){
msleep(500);
cout << "t1" << endl;
}
mutex.unlock();
wait1.wakeOne();
}
};
class Thread2:public QThread{
public:
void run(){
wait1.wait(&mutex);
for(int i=0;i<5;i++){
cout << "t2" << endl;
}
}
};
int main(){
Thread1 t1;
Thread2 t2;
t1.start();
t2.start();
t1.wait();
t2.wait();
}
结果是t1完全跑完后再跑t2:
t1
t1
t1
t1
t1
t2
t2
t2
t2
t2
也可以用QMutexLocker,这样是不是看起来更简单一点呢?
#include<iostream>
#include<QThread>
#include<QMutex>
#include<QMutexLocker>
using namespace std;
QMutex mutex;
class Thread1:public QThread{
public:
void run(){
QMutexLocker locker(&mutex);
for(int i=0;i<5;i++){
msleep(500);
cout << "t1" << endl;
}
}
};
class Thread2:public QThread{
public:
void run(){
QMutexLocker locker(&mutex);
for(int i=0;i<5;i++){
cout << "t2" << endl;
}
}
};
int main(){
Thread1 t1;
Thread2 t2;
t1.start();
t2.start();
t1.wait();
t2.wait();
}
结果同上
read与write的略有不同,读锁大家都可以读,写锁则只能一个一个写
#include<QReadWriteLock>
#include<QFile>
#include<QThread>
#include<QTextStream>
#include<iostream>
#include<QTemporaryFile>
#include<QReadLocker>
using namespace std;
QReadWriteLock readWriteLocker;
const QString fileName = "test.txt";
void readFile(QFile& file){
QTextStream ts(&file);
QString str = ts.readAll();
cout << str.toStdString() << endl;
}
class Read1:public QThread{
public:
void run(){
//加了读锁后,如果sleep,后面的可以不用等,直接读
//但是如果这里是lockForWrite()的话,无论这里sleep多久,后面的线程都得等
readWriteLocker.lockForRead();
msleep(1000);
QFile file(fileName);
if(file.open(QIODevice::ReadWrite)){
cout << "read1 start reading..." << endl;
readFile(file);
}
readWriteLocker.unlock();
file.close();//解锁后再关
}
};
class Read2:public QThread{
public:
void run(){
readWriteLocker.lockForRead();
QFile file(fileName);
if(file.open(QIODevice::ReadWrite)){
cout << "read2 start reading..." << endl;
readFile(file);
}else{
cout << "can not open!" << endl;
}
readWriteLocker.unlock();
file.close();
}
};
int main(){
Read1 r1;
Read2 r2;
r1.start();
r2.start();
r1.wait();
r2.wait();
}
read2 start reading...
This is a test file!
read1 start reading...
This is a test file!
生产者与消费者
#include<iostream>
#include<QThread>
#include<stack>
#include<QMutex>
#include<QWaitCondition>
using namespace std;
stack<int> sk;
const int sum = 10;
const int maxSize = 3;
QMutex mutex;
QWaitCondition producerWait;
QWaitCondition consumerWait;
class Producer:public QThread{
public:
void run(){
for(int i=1;i<=sum;i++){
if(sk.size()==maxSize){
cout << "stack is full,wait consumer!" << endl;
producerWait.wait(&mutex);
}
sk.push(i);
//mutex.lock();
msleep(180);
//mutex.unlock();
cout << "produce:" << i << endl;
consumerWait.wakeAll();
}
}
};
class Consumer:public QThread{
public:
void run(){
int i = 0;
for(int j=1;j<=sum;j++){
if(sk.empty()){
cout << "stack is empty,wait producer!" << endl;
consumerWait.wait(&mutex);
}
i = sk.top();
sk.pop();
//mutex.lock();
msleep(300);
//mutex.unlock();
cout << "consume:" << i << endl;
producerWait.wakeAll();
}
}
};
int main(){
Consumer con;
Producer pro;
pro.start();
con.start();
con.wait();
pro.wait();
}
stack is empty,wait producer!
produce:1
produce:2
consume:2
produce:3
produce:4
consume:3
produce:5
consume:5
produce:6
produce:7
stack is full,wait consumer!
consume:6
produce:8
stack is full,wait consumer!
consume:7
produce:9
stack is full,wait consumer!
consume:8
produce:10
consume:9
consume:10
consume:4
consume:1