通用的多线程处理模型
来源:互联网 发布:js classname事件 编辑:程序博客网 时间:2024/06/04 17:57
放代码:
class ThreadTest
{
public:
ThreadTest(){}
~ThreadTest(){}
void startup();
void addreq(int);
void _threadMain();
void _waitForNextRequest();
void _processNextRequest();
struct WorkerFunc OGRE_THREAD_WORKER_INHERIT
{
ThreadTest* mQueue;
WorkerFunc(ThreadTest* q)
: mQueue(q) {}
void operator()();
void run();
};
WorkerFunc* mWorkerFunc;
typedef std::deque<int> RequestQueue;
RequestQueue mRequestQueue;
OGRE_MUTEX(mRequestMutex)
OGRE_MUTEX(mProcessMutex)
OGRE_MUTEX(mResponseMutex)
OGRE_THREAD_SYNCHRONISER(mRequestCondition)
};
void ThreadTest::addreq(int i)
{
OGRE_LOCK_MUTEX(mRequestMutex)
mRequestQueue.push_back(i);
OGRE_THREAD_NOTIFY_ONE(mRequestCondition)
}
void ThreadTest::startup()
{
int i=3;
while(i>0)
{
mWorkerFunc = OGRE_NEW_T(WorkerFunc(this), MEMCATEGORY_GENERAL);
OGRE_THREAD_CREATE(t, *mWorkerFunc);
i--;
}
}
void ThreadTest::WorkerFunc::operator()()
{
mQueue->_threadMain();
}
void ThreadTest::WorkerFunc::run()
{
mQueue->_threadMain();
}
void ThreadTest::_threadMain()
{
while (true)
{
_waitForNextRequest();
_processNextRequest();
}
}
void ThreadTest::_waitForNextRequest()
{
OGRE_LOCK_MUTEX_NAMED(mRequestMutex, queueLock);
if (mRequestQueue.empty())
{
OGRE_THREAD_WAIT(mRequestCondition, mRequestMutex, queueLock);
}
}
void ThreadTest::_processNextRequest()
{
OGRE_LOCK_MUTEX(mProcessMutex)
{
OGRE_LOCK_MUTEX(mRequestMutex);
if (!mRequestQueue.empty())
{
int request = mRequestQueue.front();
mRequestQueue.pop_front();
cout<<request<<endl;
}
}
}
当然 里面用到了一些ogre中的线程宏,展开也就是boost的线程api:
#define OGRE_LOCK_MUTEX(name) boost::recursive_mutex::scoped_lock ogrenameLock(name);
#define OGRE_LOCK_MUTEX_NAMED(mutexName, lockName) boost::recursive_mutex::scoped_lock lockName(mutexName);
#define OGRE_THREAD_WAIT(sync, mutex, lock) sync.wait(lock);
#define OGRE_THREAD_NOTIFY_ONE(sync) sync.notify_one();
#define OGRE_THREAD_NOTIFY_ALL(sync) sync.notify_all();
#define OGRE_THREAD_SYNCHRONISER(sync) boost::condition sync;
#define OGRE_MUTEX(name) mutable boost::recursive_mutex name;
#define OGRE_THREAD_WAIT(sync, mutex, lock) sync.wait(lock);
主线程不断调用addreq()来增加请求并通知线程后马上返回 线程在得到通知后从阻塞中醒来处理请求
OGRE_LOCK_MUTEX(name):就是在范围内只允许有一个线程进入
OGRE_THREAD_WAIT(mRequestCondition, mRequestMutex, queueLock):该宏会失去queueLock,阻塞当前线程直到被通知,在返回前取得queueLock
来看_waitForNextRequest()的代码:
_waitForNextRequest()
{
OGRE_LOCK_MUTEX_NAMED(mRequestMutex, queueLock);
if (mRequestQueue.empty())
{
OGRE_THREAD_WAIT(mRequestCondition, mRequestMutex, queueLock);
}
}
首先取得范围锁queueLock,如果mRequestQueue为空,就等着,同时要注意,由于失去queueLock,其他线程会得到queueLock,并再次导致queueLock的变化
如果有三个线程,分别是1,2,3
假设线程1最先取得queueLock,然后被阻塞,同时线程2或者3会在线程1失去queueLock时取得queueLock,最终,三个线程都会被阻塞,queueLock为失去
继续往下走,假设这时主线程addreq(),那么有一个线程会被唤醒,同时得到queueLock,然后跳出该函数时,queueLock也随着超出范围变为失去,然后来看
下一个函数_processNextRequest()的代码:
_processNextRequest()
{
Request* request = 0;
{
OGRE_LOCK_MUTEX(mRequestMutex)
函数内容改了下以看得更加清楚,函数取得mRequestMutex,当其队列非空时,从队列中弹出一个请求,随后丢失mRequestMutex,并处理request
在处理完request后,将结果放进一个响应队列中,主线程在其循环中将会看到,整个流程就是这样子
总结:请求队列要注意是否为空,由于有多个线程,需要将其设为阻塞并在需要时唤醒
{
public:
ThreadTest(){}
~ThreadTest(){}
void startup();
void addreq(int);
void _threadMain();
void _waitForNextRequest();
void _processNextRequest();
struct WorkerFunc OGRE_THREAD_WORKER_INHERIT
{
ThreadTest* mQueue;
WorkerFunc(ThreadTest* q)
: mQueue(q) {}
void operator()();
void run();
};
WorkerFunc* mWorkerFunc;
typedef std::deque<int> RequestQueue;
RequestQueue mRequestQueue;
OGRE_MUTEX(mRequestMutex)
OGRE_MUTEX(mProcessMutex)
OGRE_MUTEX(mResponseMutex)
OGRE_THREAD_SYNCHRONISER(mRequestCondition)
};
void ThreadTest::addreq(int i)
{
OGRE_LOCK_MUTEX(mRequestMutex)
mRequestQueue.push_back(i);
OGRE_THREAD_NOTIFY_ONE(mRequestCondition)
}
void ThreadTest::startup()
{
int i=3;
while(i>0)
{
mWorkerFunc = OGRE_NEW_T(WorkerFunc(this), MEMCATEGORY_GENERAL);
OGRE_THREAD_CREATE(t, *mWorkerFunc);
i--;
}
}
void ThreadTest::WorkerFunc::operator()()
{
mQueue->_threadMain();
}
void ThreadTest::WorkerFunc::run()
{
mQueue->_threadMain();
}
void ThreadTest::_threadMain()
{
while (true)
{
_waitForNextRequest();
_processNextRequest();
}
}
void ThreadTest::_waitForNextRequest()
{
OGRE_LOCK_MUTEX_NAMED(mRequestMutex, queueLock);
if (mRequestQueue.empty())
{
OGRE_THREAD_WAIT(mRequestCondition, mRequestMutex, queueLock);
}
}
void ThreadTest::_processNextRequest()
{
OGRE_LOCK_MUTEX(mProcessMutex)
{
OGRE_LOCK_MUTEX(mRequestMutex);
if (!mRequestQueue.empty())
{
int request = mRequestQueue.front();
mRequestQueue.pop_front();
cout<<request<<endl;
}
}
}
当然 里面用到了一些ogre中的线程宏,展开也就是boost的线程api:
#define OGRE_LOCK_MUTEX(name) boost::recursive_mutex::scoped_lock ogrenameLock(name);
#define OGRE_LOCK_MUTEX_NAMED(mutexName, lockName) boost::recursive_mutex::scoped_lock lockName(mutexName);
#define OGRE_THREAD_WAIT(sync, mutex, lock) sync.wait(lock);
#define OGRE_THREAD_NOTIFY_ONE(sync) sync.notify_one();
#define OGRE_THREAD_NOTIFY_ALL(sync) sync.notify_all();
#define OGRE_THREAD_SYNCHRONISER(sync) boost::condition sync;
#define OGRE_MUTEX(name) mutable boost::recursive_mutex name;
#define OGRE_THREAD_WAIT(sync, mutex, lock) sync.wait(lock);
主线程不断调用addreq()来增加请求并通知线程后马上返回 线程在得到通知后从阻塞中醒来处理请求
OGRE_LOCK_MUTEX(name):就是在范围内只允许有一个线程进入
OGRE_THREAD_WAIT(mRequestCondition, mRequestMutex, queueLock):该宏会失去queueLock,阻塞当前线程直到被通知,在返回前取得queueLock
来看_waitForNextRequest()的代码:
_waitForNextRequest()
{
OGRE_LOCK_MUTEX_NAMED(mRequestMutex, queueLock);
if (mRequestQueue.empty())
{
OGRE_THREAD_WAIT(mRequestCondition, mRequestMutex, queueLock);
}
}
首先取得范围锁queueLock,如果mRequestQueue为空,就等着,同时要注意,由于失去queueLock,其他线程会得到queueLock,并再次导致queueLock的变化
如果有三个线程,分别是1,2,3
假设线程1最先取得queueLock,然后被阻塞,同时线程2或者3会在线程1失去queueLock时取得queueLock,最终,三个线程都会被阻塞,queueLock为失去
继续往下走,假设这时主线程addreq(),那么有一个线程会被唤醒,同时得到queueLock,然后跳出该函数时,queueLock也随着超出范围变为失去,然后来看
下一个函数_processNextRequest()的代码:
_processNextRequest()
{
Request* request = 0;
{
OGRE_LOCK_MUTEX(mRequestMutex)
if (!mRequestQueue.empty())
{
request = mRequestQueue.front();
mRequestQueue.pop_front();
}
}
if (request)
{
processRequestResponse(request, false);
}
函数内容改了下以看得更加清楚,函数取得mRequestMutex,当其队列非空时,从队列中弹出一个请求,随后丢失mRequestMutex,并处理request
在处理完request后,将结果放进一个响应队列中,主线程在其循环中将会看到,整个流程就是这样子
总结:请求队列要注意是否为空,由于有多个线程,需要将其设为阻塞并在需要时唤醒
- 通用的多线程处理模型
- 按键通用程序处理模型
- 通用的分页模型实现.
- COM的多线程模型
- COM的多线程模型
- COM的多线程模型
- 微软的多线程模型
- COM的多线程模型
- Chrome的多线程模型
- 多线程的基本模型
- 通用的XML处理方法
- 通用的cookie处理函数
- CRM通用模型的UML描述
- 视频质量估计的通用参数模型
- Win32多线程之微软的多线程模型
- libevent+多线程的服务器模型
- Chrome多线程模型的优缺点
- 【一】 Chrome的多线程模型
- Cassandra数据分布之1数据中心(DC)和机架(RACK)
- jQuery面试题与答案
- C 语言 位段
- C# 文件下载四方法
- 过程和函数
- 通用的多线程处理模型
- SQL语句---from 和where 查询条件的优先级
- 屏幕取词技术实现原理与关键源码
- POJ 2195 Going Home
- uva10827 - Maximum sum on a torus(圆环上的最大和)
- 黑马程序员_异常
- T-SQL逻辑查询处理的各个阶段
- C++ queue应用之电路布线(迷宫的最短路径)
- java语言程序设计 14.2 comparable