主线程向队列中添加任务;
工作线程在循环中处理任务,没有任务的时候会阻塞;
源码如下:
#include <IceUtil/Thread.h>
#include <IceUtil/Exception.h>
#include <IceUtil/Monitor.h>
#include <IceUtil/Mutex.h>
#include <IceUtil/StaticMutex.h>
#include<iostream>
#include<iomanip>
#include <list>
using namespace std;
#ifdef _DEBUG
#pragma comment(lib,"iced.lib")
#pragma comment(lib,"iceutild.lib")
#pragma comment(lib,"iceboxd.lib")
#else
#pragma comment(lib,"ice.lib")
#pragma comment(lib,"iceutil.lib")
#pragma comment(lib,"icebox.lib")
#endif
typedef IceUtil::StaticMutex CIceStaticMutex;
CIceStaticMutex oConsoleMutex = ICE_STATIC_MUTEX_INITIALIZER;
typedef IceUtil::Thread CIceThread;
typedef IceUtil::ThreadControl CIceThreadCtrl;
typedef IceUtil::Monitor<IceUtil::Mutex> CIceMonitorWithMutex;
typedef IceUtil::Exception CIceException;
//多线程互斥访问控制台
void DispStr(const string& sTxt)
{
CIceStaticMutex::Lock oLock(oConsoleMutex);
cout << sTxt << flush;
}
class CWorkQueue : public CIceThread{
private:
CIceMonitorWithMutex m_oMonitor;
list<string> m_oTaskList;
public:
CWorkQueue(){}
~CWorkQueue(){}
virtual void run(){
while(true){
string sIR = GetTaskFromQueue();//如果暂时没有任务,这次调用就会被阻塞
if(sIR == "quit") break;
DispStr("Current Work Item : " + sIR + "\n");
CIceThreadCtrl::sleep(IceUtil::Time::seconds(3));
}
}
public://开放给用户的接口:向队列添加任务
void PutTaskIntoQueue(const string& sTask)
{
CIceMonitorWithMutex::Lock oLock(m_oMonitor);
//如果任务队列为空,WorkThread就处于阻塞状态,所以MainThread要唤醒WorkThread
if(m_oTaskList.empty()) m_oMonitor.notify();
m_oTaskList.push_back(sTask);
}
private://内部使用的接口:从队列获取任务
string GetTaskFromQueue(){
CIceMonitorWithMutex::Lock oLock(m_oMonitor);
while(m_oTaskList.empty()){
m_oMonitor.wait();
}
string sTask = m_oTaskList.front(); m_oTaskList.pop_front();
return sTask;
}
};
typedef IceUtil::Handle<CWorkQueue> CWorkQueuePtr;
int main()
{
try{
CWorkQueuePtr poWorkQueue = new CWorkQueue();
CIceThreadCtrl oThreadCtrl = poWorkQueue->start();
DispStr("主线程开始给工作线程创建任务······\n");
poWorkQueue->PutTaskIntoQueue("Task1 - Connect to ftp");
poWorkQueue->PutTaskIntoQueue("Task2 - Download files");
poWorkQueue->PutTaskIntoQueue("Task3 - Disconnect");
poWorkQueue->PutTaskIntoQueue("quit");
DispStr("主线程等待工作线程结束任务······\n");
oThreadCtrl.join();
DispStr("工作线程退出后主线程跟着退出······\n");
}
catch(CIceException e){
ostringstream oos;
oos << e << endl;
DispStr(oos.str());
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}