• 服务器开发笔记


    1 使用boost asio网络库 可参照boost asio的文档示例 (异步 同步) 可参考 boost asio 一个聊天的基本框架 asio的网络通讯代码练手

    2 使用智能指针  bind  function 简化编程 提升效率 参考本博客其他文章 可参考虚函数与bind 实现设计模式的练习  

    c++11 stl 学习之 shared_ptr c++智能指针(1) c++智能指针(2)

    3 设计模式  工厂模式创建通讯包 boost factory  可参考  设计模式 工厂模式 使用shared_ptr

    4 避免粘包 包头标记包长度 再发送包  可参考 网络传输 buf 封装 示例代码

    5 线程池  io_service_pool调度算法可参考c++11 线程池学习笔记 (二) 线程池

    6 消息队列 发送接收与处理解耦

     1 #pragma once
     2 
     3 #include <boost/bind.hpp>
     4 #include <boost/function.hpp>
     5 #include <boost/thread.hpp>
     6 #include "job_queue.h"
     7 #include <iostream>
     8 
     9 using namespace std;
    10 
    11 template<typename Queue>
    12 class worker {
    13 public:
    14     typedef Queue queue_type;
    15     typedef typename Queue::job_type job_type;
    16     typedef boost::function<bool(job_type&)> func_type;
    17 public:
    18     template<typename Func>
    19     worker(queue_type& q, Func func, int n = 1);
    20 
    21     worker(queue_type& q, int n = 1);
    22 
    23     template<typename Func>
    24     void set_workerFunc(Func func) {
    25         m_func = func;
    26     }
    27 public:
    28     void start();
    29     void run();
    30     void stop();
    31 private:
    32     void do_work();
    33     queue_type & m_queue;
    34     func_type m_func;
    35     int m_nThreadNum;
    36     boost::thread_group m_threads;
    37 };
    38 
    39 template<typename Queue>
    40 template<typename Func>
    41 worker<Queue>::worker(typename worker<Queue>::queue_type& q,
    42     Func func, int n ) : m_queue(q), m_func(fuunc), m_nThreadNum(n) {
    43     if (m_nThreadNum < 1) {
    44         m_nThreadNum = 1;
    45     }
    46 }
    47 
    48 template<typename Queue>
    49 void worker<Queue>::do_work() {
    50     while (true) {
    51         job_type job = m_queue.pop();
    52         if (!m_func) {
    53             break;
    54         }
    55         else {
    56             m_func(job);
    57         }
    58     }
    59 }
    60 
    61 template<typename Queue>
    62 void worker<Queue>::start() {
    63     if (!m_func) {
    64         return;
    65     }
    66 
    67     if (m_threads.size() > 0) {
    68         return;
    69     }
    70 
    71     for (int i = 0; i < m_nThreadNum; ++i) {
    72         m_nThreads.create_thread(boost::bind(&worker::do_work, this));
    73     }
    74 }
    75 
    76 template<typename Queue>
    77 void worker<Queue>::run() {
    78     start();
    79     m_threads.join_all();
    80 }
    81 
    82 template<typename Queue>
    83 void worker<Queue>::stop() {
    84     m_func = nullptr;
    85     m_queue.stop();
    86 }
    worker.h
     1 #pragma once
     2 
     3 #include <queue>
     4 #include <boost/noncopyable.hpp>
     5 #include <boost/utility/value_init.hpp>
     6 #include <boost/thread.hpp>
     7 #include <boost/concept_check.hpp>
     8 
     9 template<typename Job>
    10 class job_queue :boost::noncopyable {
    11 public:
    12     typedef Job Job_type;
    13     typedef std::queue<Job_type> queue_type;
    14     typedef boost::mutex mutex_type;
    15     typedef typename mutex_type::scoped_lock lock_type;
    16     typedef boost::condition_variable_any condition_type;
    17 
    18     BOOST_CONCEPT_ASSERT((boost::SGIAssignable<Job_type>));
    19     BOOST_CONCEPT_ASSERT((boost::DefaultConstructible<Job_type>));
    20 public:
    21     job_queue();
    22     void push(const Job_type& x);
    23     Job_type pop();
    24     void stop();
    25 private:
    26     queue_type  m_queue;
    27     mutex_type m_mutex;
    28     condition_type m_hasJob;
    29     bool m_stop_flag;
    30 };
    31 
    32 template<typename Job>
    33 job_queue<Job>::job_queue() :m_stop_flag(false) {
    34 
    35 }
    36 
    37 template<typename Job>
    38 void job_queue<Job>::push(const Job_type& x) {
    39     lock_type lock(m_mutex);
    40     m_queue.push_back(x);
    41     m_hasJob.notify_one();
    42 }
    43 
    44 template<typename Job>
    45 typename job_queue<Job>::Job_type job_queue<Job>::pop() {
    46     lock_type lock(m_mutex);
    47     while (m_queue.empty() && !m_stop_flag) {
    48         m_hasJob.wait(m_mutex);
    49     }
    50 
    51     if (m_stop_flag) {
    52         return boost::initialized_value;
    53     }
    54 
    55     if (m_queue.empty()) {
    56         return boost::initialized_value;
    57     }
    58 
    59     Job_type tmp = m_queue.front();
    60     m_queue.pop_front();
    61     return tmp;
    62 }
    63 
    64 
    65 template<typename job>
    66 void job_queue<job>::stop() {
    67     m_stop_flag = true;
    68     m_hasJob.notify_all();
    69 }
    job_queue.h

     可参考c++11 线程池学习笔记 (一) 任务队列

    一个简单的多线程互斥设置变量类 

     1 #pragma once
     2 #include <mutex>
     3 #include <shared_mutex>
     4 
     5 
     6 template<typename T>
     7 class safe_atom {
     8 public:
     9     typedef std::shared_mutex mutex_t;
    10     safe_atom(T v);
    11     void setValue(const T& v);
    12     void getValue(T& v);
    13 private:
    14     mutex_t m_mu;
    15     T value;
    16 };
    17 
    18 template<typename T>
    19 safe_atom<T>::safe_atom::safe_atom(T v) :
    20     value(v) {}
    21 
    22 template<typename T>
    23 void safe_atom<T>::setValue(const T& v) {
    24     std::unique_lock<std::shared_mutex> lck(m_mu);
    25     value = v;
    26 }
    27 
    28 template<typename T>
    29 void safe_atom<T>::getValue(T& v) {
    30     std::shared_lock<std::shared_mutex> lck(m_mu);
    31     v = value;
    32 }
    safe_atom.h

    7 线程调度 

    8 序列化(目前基本不用自己实现 可以考虑使用 protobuf与json 或者XML) 

    可参考google protobuf VC下的使用笔记  rapidjson 的封装学习  rapidjson 的练习

    boost 序列化 例子

    1 #pragma once
    2 
    3 typedef enum empakcet_type {
    4     PACKET_TEST = 0x0800,
    5 }packet_type;
    packet_type.h
     1 #pragma once
     2 
     3 #include <iostream>
     4 #include <strstream>
     5 #include <sstream>
     6 
     7 #include <boost/serialization/serialization.hpp>
     8 #include <boost/archive/text_iarchive.hpp>
     9 #include <boost/archive/text_oarchive.hpp>
    10 #include <boost/serialization/vector.hpp>
    11 #include <boost/serialization/export.hpp>
    12 #include <boost/iostreams/stream.hpp>
    13 
    14 #include "packet_type.h"
    15 
    16 using namespace boost::archive;
    17 
    18 #define _SERIALIZATION_PACKET()    
    19 public:    
    20 virtual void serial(text_oarchive& oa) {    
    21     oa << *this;                            
    22 }                                            
    23 virtual void unserial(text_iarchive& ia) {    
    24     ia >> *this;                            
    25 }                                            
    26 int get_packet_type() {                        
    27     return static_cast<int>(m_packet_type);    
    28 }                                            
    29 protected:                                    
    30 friend boost::serialization::access;        
    31 
    32 
    33 
    34 
    35 class serial_packet {
    36     _SERIALIZATION_PACKET()
    37 protected:
    38     
    39     template<typename Archive>
    40     void serialize(Archive& ar, const unsigned int version) {
    41         ar& m_packet_type;
    42     }
    43 
    44 
    45     serial_packet(packet_type pkt_type) :m_packet_type(pkt_type) {
    46 
    47     }
    48     packet_type m_packet_type;
    49 };
    serial_packet.h
     1 #pragma once
     2 
     3 #include "serial_packet.h"
     4 
     5 
     6 class test_packet :public serial_packet {
     7     _SERIALIZATION_PACKET()
     8 public:
     9     test_packet() :serial_packet(PACKET_TEST) {}
    10 private:
    11     template<typename Archive>
    12     void serialize(Archive& ar, const unsigned int version) {
    13         ar& m_nTestNo & m_strName & m_strPwd & m_vStr;
    14     }
    15 public:
    16     int m_nTestNo;
    17     std::string m_strName;
    18     std::string m_strPwd;
    19     std::vector<std::string> m_vStr;
    20 };
    21 
    22 void print(const test_packet& packet) {
    23     std::cout << packet.m_strName << std::endl;
    24     std::cout << packet.m_strPwd << std::endl;
    25     std::cout << packet.m_nTestNo << std::endl;
    26 
    27     for (int i = 0; i < (int)packet.m_vStr.size(); ++i) {
    28         std::cout << packet.m_vStr[i] << std::endl;
    29     }
    30 }
    31 
    32 void test_mypacket() {
    33     test_packet set;
    34     set.m_strName = "hello";
    35     set.m_strPwd = "world!";
    36     set.m_nTestNo = 9999;
    37 
    38     set.m_vStr.push_back("a");
    39     set.m_vStr.push_back("b");
    40     set.m_vStr.push_back("c");
    41     set.m_vStr.push_back("c");
    42     set.m_vStr.push_back("d");
    43     const int SEND_BUFFER = 100;
    44     char buf[SEND_BUFFER];
    45     memset(buf, 0, SEND_BUFFER);
    46 
    47     std::ostrstream sa(buf, SEND_BUFFER);
    48     boost::archive::text_oarchive oa(sa);
    49     set.serial(oa);
    50 
    51     test_packet get;
    52     std::stringstream ss(buf);
    53     text_iarchive ia(ss);
    54 
    55     get.unserial(ia);
    56     print(get);
    57 }
    test_packet.h

    #include "test_packet.h"

    int main()
    {
    test_mypacket();
    return 0;
    }

    //===============================================================

    9 计时器  可参考 boost timer代码学习笔记

    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    (转)C# 泛型委托 Action<>和Func<>
    (转)ASP.NET Core 中间件与筛选器
    react中将svg做成icon组件在其他模块调用
    react简单的tab切换 (styled-components)
    计算购物车金额总和( jquery )
    js分享功能(微信,QQ,微博,空间,豆瓣等)
    AJAX入门介绍
    作为前端,你不得不知道的搜索引擎优化
    微信小程序实现图片双滑缩放大小
    swiper实现一个好看的轮播图
  • 原文地址:https://www.cnblogs.com/itdef/p/8563372.html
Copyright © 2020-2023  润新知