1.继承和多态,多线程
做棋牌demo的时候,基本模型都是事件轮询,每个事件一个线程。
所以做了一个基类和派生类。使用了常见的功能。
有几个基础知识点
1.派生类访问基类public方法:基类::方法名字 ,如。IEventLoop::Close();
2.派生类的构造函数不指定,会调用默认的基类构造函数。也可以指定,如 Loop_Log():IEventLoop(){}
3.派生类的构造顺序,基类默认构造,派生类构造。 而派生类析构,是相反,派生类析构,基类析构。
4.管理类mgr 中的成员变量,vecotr<t>,析构的时候会调用元素的析构函数,如果是原始指针类型,那么只是free 掉指针而已。如果是对象,那么必定会调用元素的析构函数。
所以感觉 class EventsMgr的数据成员用vector<shared_ptr<t>>,会更好,这样使用者就不用考虑析构的问题,让使用者能更自然使用new.到堆中。而且如果是原始指针,管理类,无法判断传入者,何时删除它,所以必须用智能指针。
5.如果要制定顺序关闭服务器。只需要更改下EventsMgr的close 函数。逐个判断是否关闭。 修改后vector元素为共享指针。
2.环形缓冲区。如果是单线程读,单线称写。就无需锁了。
#include <iostream> #include "stdio.h" #include <memory> #include <unistd.h> #include <thread> #include <vector> using namespace std; class IEventLoop { public: IEventLoop():shouldloop(true),stop(false){} virtual void Start()=0; bool IsStart() { return shouldloop; } virtual void Close() { shouldloop=false; } bool IsClosed() { return stop; } virtual ~IEventLoop(){} protected: bool shouldloop; bool stop; }; class Loop_Log:public IEventLoop { public: Loop_Log():IEventLoop(){} void Start() { while(shouldloop) { cout<<"log is runing"<<endl; sleep(1); } stop=true; } void Close() { IEventLoop::Close(); cout<<"log is closed"<<endl; } ~Loop_Log() { int a=3; } }; class Epollserver:public IEventLoop { public: Epollserver(){} void Start() { while(shouldloop) { cout<<"epollserver is runing"<<endl; sleep(1); } stop=true; } void Close() { IEventLoop::Close(); cout<<"epollserver is closed"<<endl; } ~Epollserver() { int a=3; } }; class EventsMgr { public: void AddEvent(shared_ptr<IEventLoop> _event) { if(_event!=0) { events.push_back(_event); } } void Start() { for(size_t i=0;i<events.size();++i) { auto lamfun=[](shared_ptr<IEventLoop> pi){ pi->Start();}; thread logthread=thread(lamfun,events[i]); logthread.detach(); } } void Close()const { bool allexist=false; for(size_t i=0; i<events.size(); ++i) { if (events[i]!=0x0) {events[i]->Close();} } while(!allexist) { allexist=true; for(size_t i=0; i<events.size(); ++i) { if(events[i]->IsClosed()==false) { allexist=false; break; } } } } private: vector<shared_ptr<IEventLoop> > events; }; //工厂方法.创建对象的时机延迟到工厂类.如果要替换某个对象.只需要到工厂类处理. class LoopFactory { public: static shared_ptr<IEventLoop> CreateLog() { return shared_ptr<IEventLoop>(new Loop_Log()); } static shared_ptr<IEventLoop> CreateServer() { return shared_ptr<IEventLoop>(new Epollserver()); } }; void CmdStdIn(const EventsMgr& pmgr); int main() { shared_ptr<EventsMgr> pmymgr=shared_ptr<EventsMgr>(new EventsMgr); pmymgr->AddEvent(LoopFactory::CreateLog()); pmymgr->AddEvent(LoopFactory::CreateServer()); pmymgr->Start(); CmdStdIn(*pmymgr); } void CmdStdIn(const EventsMgr& pmgr) { string cmd; cin>>cmd; while(cin>>cmd) { if("88"==cmd) { pmgr.Close(); break; } else { } } }
class RingBuff { public: RingBuff(int32_t _size); int32_t Wirte(const char* _souce,int32_t _size); int32_t Read(char* _desc,int32_t _size); int32_t Capcity(); int32_t Envalible(); ~RingBuff(); char* value_; private: int32_t size_; int32_t p_write; int32_t p_read; RingBuff(const RingBuff&); RingBuff& operator=(const RingBuff&); }; RingBuff::RingBuff(int32_t _size):p_write(0),p_read(0),size_(_size) { value_=new char[_size]; } int32_t RingBuff::Wirte(const char* _source,int32_t _size) { //最大可写值。是否超过末尾。 int real_size=_size>Envalible()?Envalible():_size; if(size_-p_write<real_size) { memcpy(value_+p_write,_source,size_-p_write); memcpy(value_,_source,real_size-size_+p_write); p_write=real_size-size_+p_write; } else { memcpy(value_+p_write,_source,real_size); p_write+=real_size; } return real_size; } int32_t RingBuff::Read(char* _desc,int32_t _size) { int real_read=_size>(size_-Envalible())?size_-Envalible():_size; if(size_-p_read<real_read) { memcpy(_desc,value_+p_read,size_-p_read); memcpy(_desc+size_-p_read,value_,real_read-size_+p_read); p_read=real_read-size_+p_read; } else { memcpy(_desc,value_+p_read,real_read); p_read+=real_read; } return real_read; } int32_t RingBuff::Capcity() { return size_; } int32_t RingBuff::Envalible() { int enLEN=0; if(p_write<p_read) { enLEN=p_read-p_write-1; } else if(p_write>=p_read) { enLEN=p_read+(size_-p_write); } return enLEN; } RingBuff::~RingBuff() { delete[] value_; }