muduo库源码解析:单例模式singleton

本文详细探讨了muduo库中单例模式(Singleton)的实现,包括利用boost::noncopyable防止复制,以及通过pthread_once保证线程安全的初始化,并在析构时注册atexit函数进行资源释放。同时,文章还提到了防止未完全类型导致错误的技巧,如使用T_must_be_complete_type确保类型完整。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单例模式实现

boost::noncopyable 防止复制,如果是自己实现,那要把构造函数拷贝构造,复制构造都私有

公有方法:

获取单例对象:instance() 返回 value 引用,(第一次 -->pthread_once --> init  ) 

私有

初始化new一单例:init()--并 atexit 注册销毁函数释放delete value

构造函数、拷贝构造,复制构造

析构函数

静态实际对象vaue指针,静态pthread_once_t


1.空用一个变量tt,声明了变量但是没有使用 编译时加 Wno-unused-parameter,会报错

(void)  tt;

2.防止delete一个不完全对象

//typedef定义一个char数组类型 T_MUST_BE_COMPELET_TYPE :char[-1]---如果T只声明没有定义-不完全类型, 没定义就没有析构函数,delete就不会调用析构函数了; char[1]--T是完全类型,即有定义,delete操作,可以调用析构函数
typedef char T_must_be_complete_type[sizeof(T)==0?-1:1];

//下面两句主要是防止报错,Werror=unused-local-typedefs,Wno-unused-parameter
T_must_be_complete_type tt;
(void)tt;

#ifndef MUDUO_BASE_SINGLETION_h
#define MUDUO_BASE_SINGLETION_h

#include <boost/noncopyable.hpp>
#include <pthread.h>
#include <stdlib.h> //atexit

namespace muduo
{

template<typename T>
class Singleton : boost::noncopyable
{
  public:
	static T& instance()
	{
		pthread_once( &ponce_, Singleton::init );
		return *value_;						 
	}

  private:
	Singleton();
	~Singleton();
	static void init()
	{
		value_ = new T();
		atexit(destroy);
	}
	static void destroy()
	{
		//定义一个char数组类型 T_MUST_BE_COMPELET_TYPE :char[-1]---如果T只声明没有定义-不完全类型 ; char[1]--T是完全类型,即有定义,delete操作,可以调用析构函数,没定义就没有析构函数,delete就不会调用析构函数了
		typedef char T_must_be_complete_type[sizeof(T)==0?-1:1];
		T_must_be_complete_type tt;
		(void)tt;
		delete value_;
	}
  private:
	  static pthread_once_t ponce_; //但是,只有一份,所以要静态!!
	  static T* value_;             //要静态!!
};

template<typename T>
pthread_once_t Singleton<T>::ponce_ = PTHREAD_ONCE_INIT;

template<typename T>
T* Singleton<T>::value_ = NULL;

}

参考:c++教程网

           muduo网络库

           linux多线程服务器端编程》.陈硕


#include <muduo/net/TcpServer.h> #include <muduo/base/Logging.h> #include <boost/bind.hpp> #include <muduo/net/EventLoop.h> // 使用muduo开发回显服务器 class EchoServer { public: EchoServer(muduo::net::EventLoop* loop, const muduo::net::InetAddress& listenAddr); void start(); private: void onConnection(const muduo::net::TcpConnectionPtr& conn); void onMessage(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer* buf, muduo::Timestamp time); muduo::net::TcpServer server_; }; EchoServer::EchoServer(muduo::net::EventLoop* loop, const muduo::net::InetAddress& listenAddr) : server_(loop, listenAddr, "EchoServer") { server_.setConnectionCallback( boost::bind(&EchoServer::onConnection, this, _1)); server_.setMessageCallback( boost::bind(&EchoServer::onMessage, this, _1, _2, _3)); } void EchoServer::start() { server_.start(); } void EchoServer::onConnection(const muduo::net::TcpConnectionPtr& conn) { LOG_INFO << "EchoServer - " << conn->peerAddress().toIpPort() << " -> " << conn->localAddress().toIpPort() << " is " << (conn->connected() ? "UP" : "DOWN"); } void EchoServer::onMessage(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer* buf, muduo::Timestamp time) { // 接收到所有的消息,然后回显 muduo::string msg(buf->retrieveAllAsString()); LOG_INFO << conn->name() << " echo " << msg.size() << " bytes, " << "data received at " << time.toString(); conn->send(msg); } int main() { LOG_INFO << "pid = " << getpid(); muduo::net::EventLoop loop; muduo::net::InetAddress listenAddr(8888); EchoServer server(&loop, listenAddr); server.start(); loop.loop(); } 这个代码应该怎么改?
最新发布
07-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值