muduo库学习笔记(-)

本文是关于muduo库的学习笔记,主要涵盖epoll、面向对象编程、muduo::base类关系及作用,如Timestamp、Atomic、Thread等,并介绍cmake的使用。同时讨论了线程池实现、异常处理和线程安全问题。

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

muduo库学习笔记

前言

code

注:个人水平有限,不能保证此文完全正确,如果错误,请不吝指出。

此文在观看《大并发服务器开发》视频时所做。

因此本文所讲基于muduo库0.9.1-beta版本,需要依赖cmake及boost.

sudo apt-get install cmake libboost-dev libboost-test-dev .

更新时间:<2018-03-12>

原创时间: <2018-03-12>

epoll/poll/select

面向对象编程与基于对象编程

  1. std::boost::function

  2. std::bootst::bind

muduo::base中类关系及作用

  1. copyable.h 一个空类,用来标识子类是值语义。

  2. Types.h 提供字符串类的声明,及两个类型转换函数模板。

    1. implicit_cast (隐式转换),使代码阅读时更明晰。
    2. down_cast (向下转型),基类指针转换为派生类指针,前提是基类指针指向派生类对象。
  3. Timestamp.h/cc 提供封装好的时间类。

    • 继承copyable,值语义。
    • 继承boot::less_than_comparable\,less_than_comparable:要求提供<,可自动实现>,<=,>=
    • BOOST_STATIC_ASSERT(sizeof(Timestamp) == sizeof(int64_t)); 编译期间的assert,在编译时就可以报错。
    • 打印64位整数使用 PRld64, printf(“%” PRld64 “\n”, value_64); 可以做到跨平台(32和64位)。
  4. Atomic.h 提供原子操作模板类。延伸阅读:无锁队列的实现

    1. 提供了AtomicInt32(用来标识线程数使用)和AtomicInt64(目前还未看出作用) 两个类。
    2. volatile关键字:确保本条指令不会因编译器的优化而省略,且要求每次直接读值。当要求使用volatile声明的变量的值时,系统总是重新从它所在的内存读取数据,而不是使用保存在寄存器中的备份。
  5. Exception.h/cc 提供异常类

    1. backtrace 栈回溯,保存各个栈帧的地址。
    2. backtrace——symbols,根据地址,转成相应的函数符号。
    3. c++会在编译时会对函数做名字改编(name mangling)。
    4. abi::__cxa_demangle 对c++的程序做名字还原。
  6. Thread.h/cc 线程类

    • Linux中进程与线程

      • Linux中每个程有一个pid,类型是pid_t,由getpid()取得。
      • Linux下每个POSIX**线**程也有一个id,类型是pthread_t,由pthread_self()取得
      • POSIX**线程id由线程库维护,其id空间是各个程独立的。(即不同的程中的线**程可能有相同的id)。
      • Linux中的POSIX线程库实现的线程其实也是一个程(LWP),只是该进程与主进程(启动线程的进程)共享一些资源而已,比如代码段,数据段等。
      • 有时候我们可能需要知道线程的真实pid。比如进程P1要向进程P2中的某个线程发送信号时,既不能使用P2的pid,更不能使用线程的pthread_id,而只能使用该线程的真实pid,称为tid。
      • 有一个函数gettid()可以得到tid,但glibc并没有实现该函数,只能通过 Linux的系统调用syscall来获取。
      • return syscall(SYS_gettid)

        1. 普通成员函数,隐含的第一个参数是 Thread*(this),调用是时候遵循 thiscall约定,某一个寄存器会保护this指针,不能直接作为pthread_create的入口函数。需要定义一个static的静态成员函数,传递this指针来调用。
        2. static AtomicInt32 numCreated_; //用来记录创建的线程数,原子操作类型,在Thread类的构造中加1,析构上减1.
        3. __thread 关键字可以定义每个线程各个的变量。只能用来修饰基本类型(内置类型(与C兼容的原始类型)或无构造函数的类(结构体)),POD类型。
        4. 将真实线程tid缓存起来,可以减少系统调用次数。
        5. namespace detail 内部使用的命名空间,对外不可见
        6. boost::is_same 用来判定两种类型是否是同一种类型
        7. pthread_atfork (void (*prepare)(void), void(*parent)(void), void(*child)(void));
      • 调用fork时,内部创建子进程前在父进程中调用prepare
      • 内部创建子进程成功后,父进程会调用parent
      • 子进程会调用child
      • fork 可能是在主线程中调用,也可能是在子线程中调用
      • fork得到一个新进程,新进程只有一个执行序列,只有一个线程(调用fork的线程被继承下来)
      • 实际上,对于编写多线程程序来说,我们最好不要再调用fork
      • 不要编写多进程多线程程序,要么用多进程要么用多线程
  7. Mutex.h 提供锁

    1. MutexLocal类
      1. 继承自boot::noncopyable,不可拷贝的,对象语义
    2. MutexLockGuard类(更常用)
      1. 使用RAII技法(通过生存期来管理资源,在构造函数中申请资源,在析构函数中释放资源)封装的MutexLocal类
  8. Condition.h/cc 条件变量类(Condition类)

    Created with Raphaël 2.1.2 Thread1 Thread1 mutex mutex Thread2 Thread2 锁住 mutex
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值