代码回顾

1.继承和多态,多线程

做棋牌demo的时候,基本模型都是事件轮询,每个事件一个线程。

所以做了一个基类和派生类。使用了常见的功能。

有几个基础知识点

1.派生类访问基类public方法:基类::方法名字  ,如。IEventLoop::Close();

2.派生类的构造函数不指定,会调用默认的基类构造函数。也可以指定,如 Loop_Log():IEventLoop(){}

3.派生类的构造顺序,基类默认构造,派生类构造。   而派生类析构,是相反,派生类析构,基类析构。

4.vecotr<t>,析构的时候会调用元素的析构函数,如果是原始指针类型,那么只是free 掉指针而已。如果是对象,那么必定会调用元素的析构函数。所以感觉  class EventsMgr的数据成员用vector<shared_ptr<t>>,会更好,这样,使用者

就不用考虑析构的问题,让使用者能更自然使用new.到堆中。

 5.如果要制定顺序关闭服务器。只需要更改下EventsMgr的close 函数。逐个判断是否关闭。

#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(){}
    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(IEventLoop* _event)
    {
        if(_event!=0)
        {
            events.push_back(_event);
        }
    }
    void Start()
    {
        for(size_t i=0;i<events.size();++i)
        {
            auto lamfun=[](IEventLoop* pi){ pi->Start();};
            thread logthread=thread(lamfun,events[i]);
            logthread.detach();
        }
    }

    void Close()
    {
        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<IEventLoop*> events;
};

int main()
{
    EventsMgr mymgr;

    Loop_Log mylog;
    mymgr.AddEvent(&mylog);

    //vector<Loop_Log> test;
    //test.push_back(mylog);

    Epollserver myserver;
    mymgr.AddEvent(&myserver);

    mymgr.Start();

    string cmd;
    cin>>cmd;

    while(cmd=="88")
    {
        mymgr.Close();
        break;
    }

}

修改后vector元素为共享指针。

#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()
    {
        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;
};

int main()
{
    EventsMgr mymgr;

    mymgr.AddEvent(shared_ptr<IEventLoop>(new Loop_Log()));
    mymgr.AddEvent(shared_ptr<IEventLoop>(new Epollserver()));

    mymgr.Start();

    string cmd;
    cin>>cmd;

    while(cmd=="88")
    {
        mymgr.Close();
        break;
    }
}
时间: 2024-07-30 19:33:27

代码回顾的相关文章

java 线程、线程池基本应用示例代码回顾

package org.rui.thread; /** * 定义任务 * * @author lenovo * */ public class LiftOff implements Runnable { protected int countDown=10; private static int taskCount=0; private final int id=taskCount++; public LiftOff(){} public LiftOff(int countDown) { thi

.net 控件开发第二天 怎么将 第一天写的代码 用到 .net中来

前面第一天 我们看到的全是 js的代码,虽然不管是BS的框架是java 还是 php,复用性 还是特别高的,  但是 写起来比较费劲,怎么办,我们能不能 更 简单点呢? 当然可以,这个时候我们就要用到  .net的自定义控件 了. 首先我们 将第一天的代码  回顾一下,(下面我们有了一个初始的改变) //这里运用的面向对象的思想 ,新建了一个按钮对象 var button = function () { this.control = null; //属性: 按钮对象的 自己 this.id =

回顾四叉树LOD地形(上)

唉!~其实这是在差不多一年前实现的东西,但当时没作好记录.放了那么久了,如果不做点总结的话,好像有点对不起自己,于是·········还是做点什么吧. 我脑洞比较小,只能大量参考"潘李亮"大神的四叉树LOD地形论文和一个叫做"曾涛"大神的代码实现,小弟在此先向诸位致敬了.下面分享本人实践之后的一点心得. 为什么要用LOD地形? 也许看完了传说中的"龙书"有关地形那章,你就知道了一个简单的地形系统是怎么实现的,无非就是根据高度图提供的高度信息以及每

Android群英传知识点回顾——第七章:Android动画机制与使用技巧

7.1 Android View动画框架 7.1.1 透明度动画 7.1.2 旋转动画 7.1.3 位移动画 7.1.4 缩放动画 7.1.5 动画集合 7.2 Android属性动画分析 7.2.1 ObjectAnimator 7.2.2 PropertyValuesHolder 7.2.3 ValueAnimator 7.2.4 动画事件的监听 7.2.5 AnimatorSet 7.2.6 在XML中使用属性动画 7.2.7 View的animate方法 7.3 Android布局动画

Android群英传知识点回顾——第六章:Android绘图机制与处理技巧

6.1 屏幕的尺寸信息 6.1.1 屏幕参数 6.1.2 系统屏幕密度 6.1.3 独立像素密度dp 6.1.4 单位转换 6.2 2D绘图基础 6.3 Android XML绘图 6.3.1 Bitmap 6.3.2 Shape 6.3.3 Layer 6.3.4 Selector 6.4 Android绘图技巧 6.4.1 Canvas 6.4.2 Layer图层 6.5 Android图像处理之色彩特效处理 6.5.1 色彩矩阵分析 6.5.2 Android颜色矩阵--ColorMatr

Swing中使用JTable动态获取数据库中的数据并显示

笔者注:本文供新手学习使用,若有一定基础,可以直接看3! 1.创建数据库: /* Navicat MySQL Data Transfer Source Server : aa Source Server Version : 50519 Source Host : localhost:3306 Source Database : test Target Server Type : MYSQL Target Server Version : 50519 File Encoding : 65001 D

《Linux内核分析》第六周学习笔记

<Linux内核分析>第六周学习笔记 进程的描述和创建 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 [学习视频时间:1小时 撰写博客时间:2小时] [学习内容:进程创建的过程.使用gdb跟踪分析内核处理函数sys_clone] 一.进程的描述 1.1 进程描述符task_struct数据结构(一) 1. 进程控制块PCB——task_struct 为了管理进程,内核

大道至简后段

从编程到工程 语言只是工具. 注重方法:有人在寺院扫了一辈子的落叶而得道,也有人因为一句话而得道. GoF 因为无数次的代码回顾而得道. 过程中的问题,就是角色.沟通和环节的问题.角色的确定,以及角色间的沟通问题,在项目过程中同样重要. 最狭义的工程,是描述“做什么”和“做到什么”.没有团队意识的软件公司将在高度过程化.通晓方法理论拥有大量工具的集团军面前必将一触即溃. 实现,是软件开发的本质需求.方法,是对既有行为的归纳总结. 思考问题的方法可以是由点及面的,也可以是统揽全局的. 工具.方法与

PHP面向对象之选择工厂和更新工厂

/* 选择工厂和更新工厂模式,这个模式的类(UpdateFactory和SelectionFactory类)就是用来创建SQL语句的. 因为涉及到之前学习的内容比较多,这里就尽量将之前相关模式的示例代码放在一起来进行学习和回顾了. 以下的代码都是代码片段而且涉及到连接数据库,无法进行整体的调试(某些部分单独拿出来的话就可以),因此重在理解. */ //更新工厂 abstract class UpdateFactory{ abstract function newUpdate(\woo\domai