
muduo
不闻窗外事
学无止境
展开
-
TcpClient
TcpServer表示服务端,那么TcpClient表示的就是客户端。TcpClient::TcpClient(EventLoop* loop, const InetAddress& serverAddr, const string& nameArg) : loop_(CHECK_NOTNULL(loop)), connector_(new Connector(loop, serverAdd原创 2020-11-09 16:04:28 · 2722 阅读 · 0 评论 -
TcpConnection
TcpConnection是muduo库中最重要的一个类。是整个网络库的核心,封装一次TCP连接。而且该类的生命期由用户和库共同控制,因为其生命期的管理更加复杂,所以该类使用shared_ptr管理,并继承了std::enable_shared_from_this<TcpConnection>。关于enable_shared_from_this可以参考这篇博客:https://blog.youkuaiyun.com/caoshangpa/article/details/79392878。void m.原创 2020-11-09 15:53:15 · 861 阅读 · 0 评论 -
Connector
该类和Acceptor有点相似,都是建立连接的,区别在于Connector是客户端使用的,Acceptor是服务端使用的,而且Connector有重连机制,还有一个区别是Acceptor是一直有效的,一直等待读事件的发生,而Connector只关心一次写事件,建立连接之后,Connector不再关心任何事件,只有等到重连的时候才会重新关心写事件。Connector::Connector(EventLoop* loop, const InetAddress& serverAddr) : lo原创 2020-11-09 15:27:09 · 607 阅读 · 0 评论 -
TcpServer
服务端类,一个服务端只需要一个该实例。TcpServer::TcpServer(EventLoop* loop, const InetAddress& listenAddr, const string& nameArg, Option option) : loop_(CHECK_NOTNULL(loop)), ipPort_(listenAddr.t原创 2020-11-09 15:18:19 · 2311 阅读 · 0 评论 -
EventLoopThreadPool
事件循环线程池,当需要多线程处理事件时使用。该类的主要成员是std::vector<std::unique_ptr<EventLoopThread>>threads_,EventLoopThread启动一个线程,在其中运行EventLoop::loop()。先说下EventLoopThread。EventLoopThread::EventLoopThread(const ThreadInitCallback& cb, .原创 2020-11-09 15:06:34 · 308 阅读 · 0 评论 -
EventLoop
EventLoop事件循环(反应器Reactor),每个线程只能有一个EventLoop实体,它负责IO和定时器时间的分派。int createEventfd(){ int evtfd = ::eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); if (evtfd < 0) { LOG_SYSERR << "Failed in eventfd"; abort(); } return evtfd;}EventLoo原创 2020-11-09 14:59:58 · 188 阅读 · 0 评论 -
Channel
class Channel : noncopyable{ public: typedef std::function<void()> EventCallback; typedef std::function<void(Timestamp)> ReadEventCallback; Channel(EventLoop* loop, int fd); ~Channel(); void handleEvent(Timestamp receiveTime); .原创 2020-11-09 14:46:52 · 5321 阅读 · 0 评论 -
Poller
在muduo中,Poller貌似这是唯一一个虚基类。EPollPoller和PollPoller继承自该类,对外提供统一的接口。因为muduo主要使用epoll接口,所以PollPoller不在分析。先看接口:class Poller : noncopyable{ public: typedef std::vector<Channel*> ChannelList; Poller(EventLoop* loop); virtual ~Poller(); /// .原创 2020-11-09 14:46:31 · 485 阅读 · 0 评论 -
eventfd
#include <sys/eventfd.h>int eventfd(unsigned int initval, int flags);《Linux/UNIX系统编程手册》自内核2.6.22起,Linux通过eventfd()系统调用额外提供了一种非标准的同步机制。这个系统调用创建了一个eventfd对象,该对象拥有一个相关的由内核维护的8字节无符号整数,它返回一个指向该对象的文件描述符。向这个文件描述符中写入一个整数将会把该整数加到对象值上。当对象值为0时对该文件描述符的read.原创 2020-11-06 13:29:21 · 156 阅读 · 0 评论 -
muduo使用的事件类型说明
在Channel::handleEventWithGuard()中,处理各种事件类型:void Channel::handleEventWithGuard(Timestamp receiveTime){ eventHandling_ = true; LOG_TRACE << reventsToString(); if ((revents_ & POLLHUP) && !(revents_ & POLLIN)) { if (logHu原创 2020-11-05 18:12:46 · 195 阅读 · 0 评论 -
TimerQueue
int createTimerfd(){ int timerfd = ::timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); if (timerfd < 0) { LOG_SYSFATAL << "Failed in timerfd_create"; } return timerfd;}struct timespec .原创 2020-11-05 14:46:25 · 219 阅读 · 0 评论 -
CurrentThread
关于stackTrace函数之前博客stackTrace说过了。__thread int t_cachedTid = 0;__thread char t_tidString[32];__thread int t_tidStringLength = 6;__thread const char* t_threadName = "unknown"; inline int tid() { if (__builtin_expect(t_cachedTid == 0, 0)) {原创 2020-11-04 18:06:29 · 279 阅读 · 0 评论 -
ThreadPool
ThreadPool::ThreadPool(const string& nameArg) : mutex_(), notEmpty_(mutex_), notFull_(mutex_), name_(nameArg), maxQueueSize_(0), running_(false){}ThreadPool::~ThreadPool(){ if (running_) { stop(); }}void ThreadP.原创 2020-11-04 16:26:50 · 154 阅读 · 0 评论 -
ThreadLocalSingleton
为啥这个名字看起来就像是ThreadLocal和Singleton的结合体,哈哈。template<typename T>class ThreadLocalSingleton : noncopyable{ public: ThreadLocalSingleton() = delete; ~ThreadLocalSingleton() = delete; static T& instance() { if (!t_value_) { .原创 2020-11-04 14:51:09 · 310 阅读 · 1 评论 -
ThreadLocal
template<typename T>class ThreadLocal : noncopyable{ public: ThreadLocal() { MCHECK(pthread_key_create(&pkey_, &ThreadLocal::destructor)); } ~ThreadLocal() { MCHECK(pthread_key_delete(pkey_)); } T& value() {.原创 2020-11-04 11:11:20 · 102 阅读 · 0 评论 -
Singleton
// This doesn't detect inherited member functions!// http://stackoverflow.com/questions/1966362/sfinae-to-check-for-inherited-member-functionstemplate<typename T>struct has_no_destroy{ template <typename C> static char test(decltype(&.原创 2020-11-04 09:34:25 · 249 阅读 · 0 评论 -
has_no_destroy
本来想写Singleton的,但是被这个结构体给难住了。于是便查了下相关资料,这篇知乎的文章讲的比较多,可以看下:https://zhuanlan.zhihu.com/p/21314708。template<typename T>struct has_no_destroy{ template <typename C> static char test(decltype(&C::no_destroy)); template <typename C>.原创 2020-11-03 18:34:46 · 676 阅读 · 3 评论 -
Acceptor
Acceptor::Acceptor(EventLoop* loop, const InetAddress& listenAddr, bool reuseport) : loop_(loop), acceptSocket_(sockets::createNonblockingOrDie(listenAddr.family())), acceptChannel_(loop, acceptSocket_.fd()), listenning_(false), idle.原创 2020-11-03 13:32:49 · 389 阅读 · 0 评论 -
Socket
Socket::~Socket(){ sockets::close(sockfd_);}bool Socket::getTcpInfo(struct tcp_info* tcpi) const{ socklen_t len = sizeof(*tcpi); memZero(tcpi, len); return ::getsockopt(sockfd_, SOL_TCP, TCP_INFO, tcpi, &len) == 0;}bool Socket::getTcpI.原创 2020-11-02 18:49:10 · 414 阅读 · 0 评论 -
InetAddress
InetAddress类就是封装了IPv4地址和IPv6地址。比较简单,这是muduo库中少有的值语义的类,所以继承的是copyable。实际上copyable只是强调可以拷贝,并没有实际意义。即使不继承该类还是可以copy。InetAddress::InetAddress(uint16_t port, bool loopbackOnly, bool ipv6){ static_assert(offsetof(InetAddress, addr6_) == 0, "addr6_ offset 0原创 2020-11-02 13:06:16 · 430 阅读 · 0 评论 -
Endian
// the inline assembler code makes type blur,// so we disable warnings for a while.#pragma GCC diagnostic push#pragma GCC diagnostic ignored "-Wconversion"#pragma GCC diagnostic ignored "-Wold-style-cast"inline uint64_t hostToNetwork64(uint64_t host6.原创 2020-11-02 11:36:57 · 378 阅读 · 0 评论 -
Thread
pid_t gettid(){ return static_cast<pid_t>(::syscall(SYS_gettid));}gettid函数用来获取线程的ID的,但是获取的不是pthread_self返回的pthread_t类型的线程ID,而是类型为gettid获取的pid_t。POSIX线程ID与Linux专有的系统调用gettid()所返回的线程ID并不相同。POSIX线程ID由线程库实现来负责分配和维护。gettid()返回的线程ID是一个由内核分配的数字,类似于.原创 2020-10-31 16:47:31 · 477 阅读 · 0 评论 -
AsyncLogging
AsyncLogging::AsyncLogging(const string& basename, off_t rollSize, int flushInterval) : flushInterval_(flushInterval), running_(false), basename_(basename), rollSize_(rollSize), t.原创 2020-10-31 15:20:56 · 193 阅读 · 0 评论 -
FileUtil
FileUtil命名空间中,是一些操作文件的工具类和方法。FileUtil::AppendFile::AppendFile(StringArg filename) : fp_(::fopen(filename.c_str(), "ae")), // 'e' for O_CLOEXEC writtenBytes_(0){ assert(fp_); ::setbuffer(fp_, buffer_, sizeof buffer_); // posix_fadvise POSIX原创 2020-10-31 14:32:34 · 437 阅读 · 0 评论 -
LogFile
LogFile类就是提供同步的文件输出,在上一篇Logging的文章中,提到了设置输出函数和刷新IO缓冲函数,使用LogFile很简单, 主要方法就是将该类的append和flush设置为Logger类的输出和刷新IO缓冲函数。// Use of this source code is governed by a BSD-style license// that can be found in the License file.//// Author: Shuo Chen (chenshuo .原创 2020-10-31 13:15:45 · 2659 阅读 · 2 评论 -
Logging
__thread char t_errnobuf[512];__thread char t_time[64];__thread time_t t_lastSecond;const char* strerror_tl(int savedErrno){ return strerror_r(savedErrno, t_errnobuf, sizeof t_errnobuf);}Logger::LogLevel initLogLevel(){ if (::getenv("MUDUO_LO.原创 2020-10-31 12:45:33 · 252 阅读 · 0 评论 -
__thread
看muduo源码,发现有很多使用__thread的地方,所以先单独写一下__thread的功能。这个特性是linux的非标准特性,需要内核(Linux2.6提供)、Pthreads实现(NPTL提供)以及C编译器(在X86-32平台上由gcc 3.3或后续版本提供)的支持。线程局部存储的主要优点在于,比线程特有数据的使用要简单。要创建线程局部变量,只要简单地在全局或静态变量的声明中包含__thread说明符即可。static __thread buf[MAX_ERROR_LEN];但凡带有这原创 2020-10-31 10:51:11 · 1190 阅读 · 0 评论 -
LogStream
这个文件涉及的内容比较多,分开描述const char digits[] = "9876543210123456789";const char* zero = digits + 9;static_assert(sizeof(digits) == 20, "wrong number of digits");const char digitsHex[] = "0123456789ABCDEF";static_assert(sizeof digitsHex == 17, "wrong number原创 2020-10-31 10:08:00 · 524 阅读 · 0 评论 -
setbuffer
在muduo库的AppendFile类的构造函数中,会使用::setbuffer(fp_,buffer_,sizeofbuffer_);将缓冲区设置为本地的buffer_,因为虽然对于行缓冲、原创 2020-10-30 13:26:35 · 1376 阅读 · 2 评论 -
fwrite_unlocked
在看muduo日志部分的时候,发现里面写文件使用的是fwrite_unlocked这个接口,之前没有见过,不过看名称就大体知道什么意思:fwrite的线程不安全版本。而且这样的接口有一个系列。因为没有用过,所以今天做了一个测试,方便以后使用。测试代码:#include <stdio.h>#include <string.h>#include <pthread.h>#include <sys/time.h>#define THREAD_NUM 5原创 2020-10-30 13:05:34 · 3148 阅读 · 4 评论 -
stackTrace
在muduo的CurrentThread.cc源文件中,有一个函数stackTrace,感觉很有意思,就研究了下是做什么的。string stackTrace(bool demangle){ string stack; const int max_frames = 200; void* frame[max_frames]; int nptrs = ::backtrace(frame, max_frames); char** strings = ::backtrace_symbol原创 2020-10-29 18:17:42 · 722 阅读 · 1 评论 -
Condition
Condition.hclass Condition : noncopyable{ public: explicit Condition(MutexLock& mutex) : mutex_(mutex) { MCHECK(pthread_cond_init(&pcond_, NULL)); } ~Condition() { MCHECK(pthread_cond_destroy(&pcond_)); } void .原创 2020-10-29 13:39:42 · 140 阅读 · 0 评论 -
CountDownLatch
CountDownLatch::CountDownLatch(int count) : mutex_(), condition_(mutex_), count_(count){}void CountDownLatch::wait(){ MutexLockGuard lock(mutex_); while (count_ > 0) { condition_.wait(); }}void CountDownLatch::countDown().原创 2020-10-29 13:19:56 · 341 阅读 · 0 评论 -
MutexLock
class CAPABILITY("mutex") MutexLock : noncopyable{ public: MutexLock() : holder_(0) { MCHECK(pthread_mutex_init(&mutex_, NULL)); } ~MutexLock() { assert(holder_ == 0); MCHECK(pthread_mutex_destroy(&mutex_)); } // .原创 2020-10-29 08:34:43 · 740 阅读 · 0 评论 -
noncopyable
class noncopyable{ public: noncopyable(const noncopyable&) = delete; void operator=(const noncopyable&) = delete; protected: noncopyable() = default; ~noncopyable() = default;};class copyable{ protected: copyable() = default; .原创 2020-10-28 18:30:00 · 768 阅读 · 0 评论 -
通过muduo的Atomic.h学习原子操作
最新在读muduo源码,想写一个源码阅读的系列,就以这个为开篇吧源码如下:template<typename T>class AtomicIntegerT : noncopyable{ public: AtomicIntegerT() : value_(0) { } // uncomment if you need copying and assignment // // AtomicIntegerT(const AtomicIntegerT&a原创 2020-10-28 18:18:38 · 684 阅读 · 0 评论