hi,it's onebird‘s blog。My homepage is onebird.net.
onebird | 25 八月, 2006 22:57
通过这个线程池的封装来复习一下设计模式。(我会把代码在最后一篇打包)
下复习 函数对象化
这个线程池有如下特定。
cpp跨平台(这部分依赖公司保密代码不公开)
任务池可配置(默认使用std::queue 也可以用堆和循环队列实现)
函数对象化 可以多个任务共用一组线程池
可暂停 可停止 可继续
接口简单
用它来开发中等规模服务器是非常方便的
通过这个线程池的封装来复习一下设计模式。(我会把代码在最后一篇打包)
这个线程池有如下特定。
cpp跨平台(这部分依赖公司保密代码不公开)
任务池可配置(默认使用std::queue 也可以用堆和循环队列实现)
函数对象化 可以多个任务共用一组线程池
可暂停 可停止 可继续
接口简单
用它来开发中等规模服务器是非常方便的
---------------------------------
对象化的函数
<<Think in Patterns with Java>> 一书的这样解释函数对象
In Advanced C++:Programming Styles And Idioms
(Addison-Wesley, 1992), Jim Coplien coins the term functor which is
an object whose sole purpose is to encapsulate a function (since “functor” has a
meaning in mathematics, in this book I shall use the more explicit term
function object). The point is to decouple the choice of function to be
called from the site where that function is called.
This term is mentioned but not used in Design Patterns. However, the theme of the function object is repeated in a number of patterns in that book.
我们在这座一个示范
class ThreadJob
{
public:
inline virtual bool execute()
{
delete this;
return true;
}
ThreadJob() {}
};
一般自己实现未封装的线程池总要自己先定义几组不同的stdcall的线程函数。然后启动一组这样的线程。
现在不需要这样的函数了,只需要继承ThreadJob 然后重载
execute()函数。比如以下这个类就完成了一个登陆服务器的多线程测试
class MyJob : public ThreadJob
{
public:
inline virtual bool execute()
{
printf("enter exec
");
unsigned char email_len;
char email[200];
unsigned long systemid =0;
int ret;
memset(email,0,200);
read(m_so, &email_len,1);
if( email_len < 200){
printf("Email len:%d
",email_len);
ret = read(m_so, email, email_len);
printf("in myjob exec
");
printf("email:%s
",email);
if(ret == email_len)
{
printf("ret == %d
",ret);
systemid = QueryUserSysId(email, NULL);
printf("systemid %d
",systemid);
}
}else{
systemid = 0 ;
}
write(m_so,&systemid,SYSID_LEN);
close(m_s
;
return ThreadJob::execute();
};
MyJob(int sock):m_so(sock){};
virtual ~MyJob(){};
protected:
int m_so;
};
#endif
main.cpp中只需要
ThreadPool thepool;
thepool.set_threadcount(100)
for(size_t i = 0 ; i<100000 ; i++){
socket so = CONNECT(..)
thepool.addjob(New MyJob(s
)
}
那么我们的登陆函数就会通过子类虚函数回调被线程池执行。这样一来我们的目的就达到了。
// Author
nebird
// Date 2006.08.22
// For Cross Thread Pool Class
//////////////////////////////////////////////////////////////////////
#ifndef _THREAD_H_
#define _THREAD_H_
#include "mthread.h"
#include "mutex.h"
//#include <pthread.h>
#include "threadjob.h"
#include "threadpool.h"
class ThreadPool;
class Thread //线程封装 作为ThreadPool管理对象
{
public:
inline ThreadPool * get_threadpool() {
return m_pthreadPool;
}
void run();
Thread( ThreadPool * pPool );
virtual ~Thread();
protected:
ThreadPool * m_pthreadPool ;
MThread m_thread;
MMutex m_mutex;
bool m_fquit;
};
#endif
#ifndef _THREADJOB_H_
#define _THREADJOB_H_
#include <time.h>
#include <queue>
class ThreadJob
{
public:
inline virtual bool execute()
{
delete this;
return true;
}
ThreadJob() {
time(&m_ts);
}
virtual ~ThreadJob() {}
protected:
time_t m_ts;
};
class JobPool{//抽象基类 用于内置任务池定制
public:
virtual void push(ThreadJob *)=0;
virtual ThreadJob * front()=0;
virtual void pop()=0;
virtual size_t size()=0 ;
};
class DefaultJobPool:public JobPool{ //默认任务池
public:
virtual void push(ThreadJob *);
virtual ThreadJob * front();
virtual void pop();
virtual size_t size();
private:
std::queue<ThreadJob *> jobs ;
};
#endif
// Author
nebird
// Date 2006.08.22
// For Cross Thread Pool Class
//////////////////////////////////////////////////////////////////////
#ifndef _THREADPOOL_H_
#define _THREADPOOL_H_
#include <queue>
#include <vector>
#include <mthread.h>
#include <mutex.h>
//#include <unistd.h>
class Thread;
;
class ThreadPool
{
public:
void pause();
bool is_pause();
void un_pause();
inline bool is_stop() { return m_fstop; }
void add_thread(Thread* pthread);
inline long get_threadcount() {return m_nthreadcount;}
inline long get_jobcount()
{
m_mutex.Lock();
int count = m_pjobs->size();
m_mutex.Unlock();
return count;
}
void stop();
void set_threadcount(int nthreads);
inline void add_job(ThreadJob* pjob)
{
if (m_fstop)
{
delete pjob;
return;
}
m_mutex.Lock();
m_pjobs->push(pjob);
m_mutex.Unlock();
m_signal.Signal();
}
inline MSemaphore * get_object() { return & m_signal; }
ThreadPool( JobPool * JobPoolPtr = new DefaultJobPool );
virtual ~ThreadPool();
inline ThreadJob* get_next()
{
ThreadJob* p = NULL;
m_mutex.Lock();
m_signal.Wait(5000);
if (m_pjobs->size() > 0)
{
p = m_pjobs->front();
if(p != NULL){
m_pjobs->pop();
}
}
m_mutex.Unlock();
return p;
}
protected:
MSemaphore m_signal;
JobPool * m_pjobs;
std::vector< Thread* > m_threads;
MMutex m_mutex;
int m_nthreadcount;
bool m_fstop;
bool m_bPause ;
};
#endif
------------------------------------------------------
跟上Think in Patterns with java的相关章节
Command: choosing the operation at run-time
This is the function object in its purest sense: a method
that’s an object[10].
By wrapping a method in an object, you can pass it to other methods or objects
as a parameter, to tell them to perform this particular operation in the process
of fulfilling your request.
//: c06:CommandPattern.java
import java.util.*;
import com.bruceeckel.test.*;
interface Command {
void execute();
}
class Hello implements Command {
public void execute() {
System.out.print("Hello ");
}
}
class World implements Command {
public void execute() {
System.out.print("World! ");
}
}
class IAm implements Command {
public void execute() {
System.out.print("I'm the command pattern!");
}
}
// An object that holds commands:
class Macro {
private List commands = new ArrayList();
public void add(Command c) { commands.add(c); }
public void run() {
Iterator it = commands.iterator();
while(it.hasNext())
((Command)it.next()).execute();
}
}
public class CommandPattern extends UnitTest {
Macro macro = new Macro();
public void test() {
macro.add(new Hello());
macro.add(new World());
macro.add(new IAm());
macro.run();
}
public static void main(String args[]) {
new CommandPattern().test();
}
} ///:~
The primary point of Command is to allow you to
hand a desired action to a method or object. In the above example, this provides
a way to queue a set of actions to be performed collectively. In this case, it
allows you to dynamically create new behavior, something you can normally only
do by writing new code but in the above example could be done by interpreting a
script (see the Interpreter pattern if what you need to do gets very
complex).
Another example of Command is
c12:DirList.java. The DirFilter class is the command object which
contains its action in the method accept( ) that is passed to the
list( ) method. The list( ) method determines what to include in
its result by calling accept( ).
Design Patterns says that “Commands are an object-oriented replacement for callbacks[11].” However, I think that the word “back” is an essential part of the concept of callbacks. That is, I think a callback actually reaches back to the creator of the callback. On the other hand, with a Command object you typically just create it and hand it to some method or object, and are not otherwise connected over time to the Command object. That’s my take on it, anyway. Later in this book, I combine a group of design patterns under the heading of “callbacks.”
rbyue@mail.com | 12/02/2007, 08:47
Carol | 14/02/2007, 18:33
福建 龙岩 永定 南开 酷讯 微软 搜索 广告 推荐 IM 网络应用 技术研发,工程管理 音乐 旅游 IPhone
| « | 八月 2006 | » | ||||
|---|---|---|---|---|---|---|
| 一 | 二 | 三 | 四 | 五 | 六 | 日 |
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 | |||
Re: 小作品 一个接口简单的C++线程池(1) Function Object 示例
momo | 03/12/2006, 19:12