线程之间,经常有通讯,这里讨论一种用消息进行通讯。
数据种类:object 和 buffer 。一种是将object打包成buffer,然后传输,到达后,再将buffer解包。这种很容易理解,结构简单,但需要进行多次内存拷贝,不实惠。另一种是将object的指针打包成buffer。
还有一种,是定义消息基类,通过这个基类的指针进行传输。各种类型的对象,都继承一个子类,提供一通用模板,减少代码量,提供->操作符,和一元*操作符。将这对象当指针对象。这样,简单的消息体就完成了。当然,再提供一个swap操作符,以便本地和new出来的对象进行内部交换。减少赋值等产生的问题,且不允许拷贝。
线程则是一个命令模式,接收到消息,就提交给处理此消息的任务。
道远且深,这个课题,慢慢细究,然后以实践验证之。
- class IMsg
- {
- virtual ~IMsg(){}
- };
- template<typename T>
- class TMsg:public IMsg
- {
- T * p;
- TMsg(){p=new T();}
- ~TMsg(){delete p;p=NULL;}
- };
- Send(target,IMsg*);
下面给个比较完整的demo:
- #include <list>
- #include <iostream>
- using namespace std;
- class IMsg
- {
- public:
- virtual ~IMsg(){}
- };
- template<typename T>
- class TMsg:public IMsg
- {
- public:
- T * m_point;
- TMsg(){m_point=new T();}
- TMsg(T*point){m_point=point;}
- T* operator->()
- {
- return m_point;
- }
- ~TMsg(){delete m_point;m_point=NULL;}
- };
- list<IMsg*> msgList;
- void Send(IMsg *pMsg)
- {
- cout<<"send base"<<endl;
- msgList.push_back(pMsg);
- }
- template<typename T>
- void Send(TMsg<T> * p)
- {
- Send((IMsg*)p);
- }
- template<typename T>
- void Send(T*object)
- {
- cout<<"send template"<<endl;
- IMsg *msg=new TMsg<T>(object);
- Send(msg);
- }
- IMsg*Recv()
- {
- if(msgList.size()==0)
- return NULL;
- IMsg * res=msgList.front();
- msgList.pop_front();
- return res;
- }
- template<typename T>
- TMsg<T> * Recv()
- {
- if(msgList.size()==0)
- return NULL;
- IMsg * res=msgList.front();
- TMsg<T> * tres=dynamic_cast<TMsg<T>*>(res);
- if(tres!=NULL)
- {
- msgList.pop_front();
- return tres;
- }
- return NULL;
- }
- class Output
- {
- public:
- void print()
- {
- cout<<"hello"<<endl;
- }
- };
- int main()
- {
- TMsg<char> *pmsg=new TMsg<char>(new char[255]);
- sprintf(pmsg->m_point,"hello 2");
- Send(new Output());
- Send(pmsg);
- TMsg<Output>*p=Recv<Output>();
- (*p)->print();
- p=Recv<Output>();
- if(p==NULL)
- cout<<"Output NULL"<<endl;
- TMsg<char> *p2=Recv<char>();
- cout<<p2->m_point<<endl;
- return 0;
- }