スレッド間通信簡(1)
スレッド間では,しばしば通信があり,ここではメッセージによる通信について議論する.
データ種別:objectとbuffer.1つはobjectをbufferにパッケージ化し、転送し、到着したらbufferをパケット解除することです.これは分かりやすく、構造は簡単ですが、複数回のメモリコピーが必要で、お得ではありません.もう1つはobjectのポインタをbufferにパッケージすることです.
もう1つは,メッセージベースクラスを定義し,このベースクラスのポインタで伝送することである.さまざまなタイプのオブジェクトは、サブクラスを継承し、汎用テンプレートを提供し、コード量を減らし、->オペレータ、およびメタ*オペレータを提供します.このオブジェクトをポインタオブジェクトとします.これで、簡単なメッセージボディが完成します.もちろん、ローカルとnewから出てきたオブジェクトを内部交換するためにswapオペレータをもう1つ提供します.割り当てなどの問題を低減し、コピーは許可されません.
スレッドはコマンドモードで、メッセージを受信すると、このメッセージを処理するタスクにコミットされます.
道は遠くて深くて、この課題は、ゆっくりと細かく研究して、それから実践で検証します.
以下に、比較的完全なdemoを示します.
データ種別:objectとbuffer.1つはobjectをbufferにパッケージ化し、転送し、到着したらbufferをパケット解除することです.これは分かりやすく、構造は簡単ですが、複数回のメモリコピーが必要で、お得ではありません.もう1つはobjectのポインタをbufferにパッケージすることです.
もう1つは,メッセージベースクラスを定義し,このベースクラスのポインタで伝送することである.さまざまなタイプのオブジェクトは、サブクラスを継承し、汎用テンプレートを提供し、コード量を減らし、->オペレータ、およびメタ*オペレータを提供します.このオブジェクトをポインタオブジェクトとします.これで、簡単なメッセージボディが完成します.もちろん、ローカルとnewから出てきたオブジェクトを内部交換するためにswapオペレータをもう1つ提供します.割り当てなどの問題を低減し、コピーは許可されません.
スレッドはコマンドモードで、メッセージを受信すると、このメッセージを処理するタスクにコミットされます.
道は遠くて深くて、この課題は、ゆっくりと細かく研究して、それから実践で検証します.
- 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;
- }