线程处理问题常常基于需要对任务进行串行化上
要使事情有序地进行处理
使用队列可以采用同步的方式访问其内部元素
就可以解决很多线程处理问题
//: C11:TQueue.h
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
#ifndef TQUEUE_H
#define TQUEUE_H
#include <deque>
#include "zthread/Thread.h"
#include "zthread/Condition.h"
#include "zthread/Mutex.h"
#include "zthread/Guard.h"
template<class T> class TQueue {
ZThread::Mutex lock;
ZThread::Condition cond;
std::deque<T> data;
public:
TQueue() : cond(lock) {}
void put(T item) {
ZThread::Guard<ZThread::Mutex> g(lock);
data.push_back(item);
cond.signal();
}
T get() {
ZThread::Guard<ZThread::Mutex> g(lock);
while(data.empty())
cond.wait();
T returnVal = data.front();
data.pop_front();
return returnVal;
}
};
#endif // TQUEUE_H ///:~
通过在标准C++库的双端队列deque上添加内容建立起来
1 加入同步以确保在同一时刻不会有两个线程添加对象
2 加入wait()和signal()以便在队列为空时让消费者线程自动挂起
并在有多个元素可用时恢复执行
对LiftOff对象的串行化进行测试
消费者是LiftOffRunner
把每个LiftOff对象从TQueue中取出来并直接执行
//: C11:TestTQueue.cpp {RunByHand}
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
//{L} ZThread
#include <string>
#include <iostream>
#include "TQueue.h"
#include "zthread/Thread.h"
#include "LiftOff.h"
using namespace ZThread;
using namespace std;
class LiftOffRunner : public Runnable {
TQueue<LiftOff*> rockets;
public:
void add(LiftOff* lo) { rockets.put(lo); }
void run() {
try {
while(!Thread::interrupted()) {
LiftOff* rocket = rockets.get();
rocket->run();
}
} catch(Interrupted_Exception&) { /* Exit */ }
cout << "Exiting LiftOffRunner" << endl;
}
};
int main() {
try {
LiftOffRunner* lor = new LiftOffRunner;
Thread t(lor);
for(int i = 0; i < 5; i++)
lor->add(new LiftOff(10, i));
cin.get();
lor->add(new LiftOff(10, 99));
cin.get();
t.interrupt();
} catch(Synchronization_Exception& e) {
cerr << e.what() << endl;
}
getchar();
} ///:~
输出
ThreadQueue created
User thread created.
Reference thread created.
1 reference-thread added.
pollPendingThreads()
1 user-thread added.
Thread starting...
0:9
0:8
0:7
0:6
0:5
0:4
0:3
0:2
0:1
0:0
Liftoff!
1:9
1:8
1:7
1:6
1:5
1:4
1:3
1:2
1:1
1:0
Liftoff!
2:9
2:8
2:7
2:6
2:5
2:4
2:3
2:2
2:1
2:0
Liftoff!
3:9
3:8
3:7
3:6
3:5
3:4
3:3
3:2
3:1
3:0
Liftoff!
4:9
4:8
4:7
4:6
4:5
4:4
4:3
4:2
4:1
4:0
Liftoff!
99:9
99:8
99:7
99:6
99:5
99:4
99:3
99:2
99:1
99:0
Liftoff! //这里按回车
Exiting LiftOffRunner
Thread joining...
Thread exiting...
insertPendingThread()
1 pending-thread added.
任务被main()函数置于TQueue队列上
被LiftOffRunner从TQueue队列上取走
LiftOffRunner可用忽略同步问题
因为问题由TQueue解决