zoukankan      html  css  js  c++  java
  • 代码回顾

    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_; 
    }
  • 相关阅读:
    【win10系统问题】远程桌面登录一次后,第二次登录看不到用户名和密码输入框
    如何更改Arcmap里经纬度小数点后面的位数?
    腾讯视频qlv格式转换MP4普通视频方法
    kettle_Spoon 修改共享DB连接带汉字引发的错误
    AutoCAD2015激活码和密钥
    SQL获取本周,上周,本月,上月第一天和最后一天[注:本周从周一到周天]
    SQL语句 不足位数补0
    c# winform 服务器提交了协议冲突. Section=ResponseStatusLine
    java.net.ProtocolException: Server redirected too many times
    MarkDown空格缩进的方法
  • 原文地址:https://www.cnblogs.com/lsfv/p/6678666.html
Copyright © 2011-2022 走看看