自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(142)
  • 收藏
  • 关注

原创 muduo库学习之设计与实现01——什么都不做的EventLoop

东阳的学习笔记文章目录一. 基本接口1.1 构造函数1.2 loop成员函数二、工具函数2.1 getEventLoopOfCurrentThread()2.2 void EventLoop::abortNotInLoopThread一. 基本接口构造函数、析构函数、loop() 成员函数EventLoop是不可拷贝的muduo中大多数类都是不可拷贝的。class EventLoop : boost::noncopyable{public: EventLoop(); ~Eve.

2021-02-04 11:48:42 178

转载 linux惊群效应

原文连接:https://xiaomaweifu.blog.youkuaiyun.com/article/details/78648798linux惊群效应详细的介绍什么是惊群,惊群在线程和进程中的具体表现,惊群的系统消耗和惊群的处理方法。1、惊群效应是什么?惊群效应也有人叫做雷鸣群体效应,不过叫什么,简言之,惊群现象就是多进程(多线程)在同时阻塞等待同一个事件的时候(休眠状态),如果等待的这个事件发生,那么他就会唤醒等待的所有进程(或者线程),但是最终却只可能有一个进程(线程)获得这个时间的“控制权”,.

2021-02-03 18:55:53 470

原创 muduo库学习之详解muduo多线程模型(常见的并发网络服务器设计方案)

东阳的学习笔记12种常见方案下表是作者总结的12种常见方案,其中:互通:开发chat服务时,多个客户连接之间是否能方便地交换数据

2021-02-03 17:16:09 945

原创 muduo库学习之C++多线程系统编程精要07——多线程与 fork、多线程与signal

东阳的学习笔记1. 多线程与 fork多线程与 fork() 的协作性很差。这是 POSIX 系列操作系统的历史包袱。1.1 fork 一般不能在多线程程序中使用因为 Linux 的 fork() 只克隆当前线程的 thread of control,不克隆其他线程。fork() 之后,除了当前线程之外的所有线程都消失了。forkall() 是很难办到的。因为其他线程可能等在 condition variable 上面,可能阻塞在系统调用上、可能等着 metux 以进入临界区1.2 fo.

2021-02-02 09:20:46 324

原创 muduo库学习之C++多线程系统编程精要06——RAII与fork

东阳的学习笔记审慎使用 fork()fork()可能会导致资源泄漏但是,假如程序会fork(),上面的假设就会被破坏了考虑下面这个例子,Foo对象构造了一次,但是析构了两次int main(){ Foo foo; //调用构造函数 fork(); //fork为两个进程 foo.doit(); //在父子进程中都使用foo //析构函数会被调用两次,父进程和子进程各一次}还可能会出现的错误:如果Foo class封装了某种资源,而.

2021-02-02 09:20:25 192

原创 muduo库学习之C++多线程系统编程精要05——用RAII包装文件描述符

东阳的学习笔记POSIX分配文件描述符的方式容易串话因为 POSIX 标准要求每次打开新文件(含socket)的时候,必须使用当前最小可用的文件描述符号码。这样可能导致串话。多线程程序如何避免串话在单线程程序中,可以通过某种全局表来避免串话。但是这种方法显然不适合多线程场景!在C++中,要解决串话问题,很简单:RAII。只需要将文件描述符对象包装在 Socket 对象中。在析构函数里关闭文件描述符即可。服务器程序中不应该关闭标准输出和标准错误因为有些第三方库会在紧急情况下往 stdou.

2021-02-01 21:16:25 227

原创 muduo库学习之C++多线程系统编程精要04——多线程与IO

东阳的学习笔记在进行多线程网络编程的时候,几个自然的问题是:如何处理IO?(一个文件只由一个进程中的一个线程来读写,这种做法显然是正确的)能否多个线程同时读写同一个 socket 文件描述符?(最好不要)我们知道用多线程同时处理多个 socket 通常可以提高效率,那么处理同一个 socket 呢?系统调用时线程安全的,但是使用不是线程安全的首先,**操作文件描述符的系统调用本身是线程安全的,**我们不用担心多个线程同时操作文件描述符会造成进程崩溃或内核崩溃但是,多个线程同时.

2021-02-01 20:45:17 420

原创 muduo库学习之C++多线程系统编程精要03——线程的创建与销毁

东阳的学习笔记线程的创建线程的创建比销毁要容易得多,只需要遵守下面几条原则即可:程序库不应该在未提前告知的情况下创建自己的“背景线程”尽量用相同的方式创建线程,例如muduo::Thread在进入main()函数之前不应该启动线程程序中线程的创建最好能在初始化阶段全部完成1. 程序库不应该在未提前告知的情况下创建自己的“背景线程”线程是稀缺资源,如果程序库暗地里使用了线程,可能会导致高估系统的可用资源。一旦程序中有不只一个线程就很难安全的 fork,因此程序库最好不要偷偷使用线程.

2021-02-01 16:47:59 822

转载 muduo库学习之C++多线程系统编程精要02——C/C++系统库的线程安全性

一、C/C++的线程库原先的C/C++标准(C89/C99/C++03)并没有涉及线程,新版的C/C++标准(C11和C++11)规定了程序在多线程下的语意,C++11还定义了一个线程库(std::thread)内存模型(memory model)对于标准而言,关键的不是定义线程库,而是规定内存模型特别是规定一个线程对某个共享变量的修改何时能被其他线程看到,这称为内存序(memory ordering)或者内存能见度 (memory visibility)从理论上讲,如果没有合适的内存模型

2021-02-01 15:58:33 251

转载 muduo库学习之C++多线程系统编程精要01——基本线程原语的选用、Linux上的线程标识、善用__thread关键字、Linux新增系统调用的启示

东阳的学习笔记学习多线程面临的最大的思维转变有两点:当前线程可能随时会被切出去,或者说被抢占了。多线程程序中事件的发生顺序不再有全局统一的先后关系多线程程序的正确性不能依赖于任何一个线程的执行速度,不能通过原地等待(sleep)来假定其他线程的事件已经发生,而必须通过适当的同步来让当前线程能够看到其他线程事件的结果。无论线程执行得快与慢(被操作系统切换出去的越多执行地越慢), 程序都应该能够正常工作。`一、基本线程原语的选用我认为用C/C++编写跨平台(只针对POSIX操作系统).

2021-02-01 15:44:35 274

转载 muduo库学习之多线程服务器的适用场合

文章目录正名必须用单线程的场合基于进程的分布式系统设计单线程程序的优势多线程程序有性能优势吗?适用多线程程序的场景线程的分类“服务器开发”包罗万象,本文所指的“服务器开发”的含义请见《常用模型》一文,一句话形容是:跑在多核机器上的 Linux 用户态的没有用户界面的长期运行的网络应用程序。“长期运行”的意思不是指程序 7x24 不重启,而是程序不会因为无事可做而退出,它会等着下一个请求的到来。例如 wget 不是长期运行的,httpd 是长期运行的。正名与前文相同,本文的“进程”指的是 fork()

2021-02-01 14:33:07 259

转载 muduo库学习之常用编程模型04——常用编程模型与进程间通信方式的选择

东阳的学习笔记文章目录1. 单线程服务器常用地编程模型2. 典型的多线程服务器的线程模型One loop per thread线程池归纳3. 进程间通信与线程间通信进程间通信原文链接:https://blog.youkuaiyun.com/yuyin86/article/details/70864241. 单线程服务器常用地编程模型常用的单线程编程模型见https://blog.youkuaiyun.com/qq_22473333/article/details/112910686在高性能的网络程序中,使用得.

2021-02-01 14:04:51 439

原创 muduo库学习之适用场合和常用编程模型03——进程和线程

东阳的学习笔记进程和线程每个进程有自己的独立空间。“在同一个进程” 还是 “不在同一个进程”是系统功能划分的重要决策点。线程的特点是共享地址空间,从而高效地共享数据,一台机器上的多个进程能高效地共享代码段(操作系统可以映射为同样的物理内存),但不能共享数据。如果多个进程大量地共享内存,等于是把多进程程序当作多线程来写,掩耳盗铃!为什么要使用多线程作者认为是为了更好地发挥多核处理器的效能。如果只有一块CPU、一个执行单元,按状态机的思路去写程序是最高效的。...

2021-02-01 12:49:17 126 1

转载 muduo库学习之适用场合和常用编程模型02——线程

原文链接:https://blog.youkuaiyun.com/zhoucheng05_13/article/details/976121351 线程创建创建一个线程,并在主线程和子线程中打印进程id、线程id。实例代码#include "apue.h"#include<pthread.h>pthread_t tdno;//打印进程id、线程idvoid printids(const char* s){ pid_t pid; pthread_t tid; .

2021-02-01 11:59:40 200

原创 muduo库学习之适用场合和常用编程模型01——fork函数(多进程)

东阳的学习笔记

2021-02-01 11:24:24 206

原创 muduo库学习之线程同步08——总结

东阳的学习笔记1. 内容总结前面几篇文章的内容归纳如下:线程同步的四项原则,尽量使用高层同步设施(线程池、队列、倒计时)使用普通互斥器和条件变量完成剩余的同步任务,采用 RAII惯用手法和 Scoped Locking。所谓的四项原则即:muduo库学习之线程同步01——互斥器mutex中所提到的使用原则2. 文章汇总muduo库学习之线程同步01——互斥器mutexmuduo库学习之线程同步02——条件变量muduo库学习之线程同步03——不要用读写锁和信号量muduo库.

2021-01-31 16:40:40 149

原创 muduo库学习之线程同步07——CopyOnWrite

东阳的学习笔记CopyOnWriter1 什么是COW?COW字面意思写时复制,是一种并发场景下的共享数据策略。顾名思义,它的基本思想是大家共享同一份数据,读的时候不加锁,直接读取数据;更新数据时在其拷贝副本上操作,在这个新拷贝的数据上演绎更新操作,然后再用这个新数据替换老数据。2 借 shared_ptr 实现 copy-on-write在 互斥器 那篇文章中提到了一个死锁的例子。在这里我们来看看如何使用 COW 来解决这个问题:先将数据结构改成:typedef std::vect.

2021-01-31 16:16:50 332

转载 muduo库学习之线程同步06——Singleton单例实现

文章目录一、DCL二、pthread_once原文链接:https://blog.youkuaiyun.com/qq_41453285/article/details/104885869一、DCL研究Singleton的线程安全实现的历史会发现很多有意思的事情,人们一度认为double checked locking(缩写为DCL)是王道,兼顾了效率与正确性。后来有“神牛”指出由于乱序执行的影响,DCL是靠不住的。可以参阅:http://www.cs.umd.edu/~pugh/java/memory

2021-01-30 17:34:37 222

转载 muduo库学习之线程同步05——MutexLock、MutexLockGuard的封装

文章目录一、MutexLock、MutexLockGuard的封装MutexLockMutexLockGuard二、Condition的封装>Condition关于条件变量与互斥器的使用三、总结一、MutexLock、MutexLockGuard的封装MutexLock:封装临界区(critical section),这是一个简单的资源类,用RAII手法封装互斥器的创建与销毁。MutexLock一般是别的class的数据成员临界区在Windows上是struct CRITICAL_SEC

2021-01-30 17:27:15 368

原创 muduo库学习之线程同步04——sleep不是同步原语

东阳的学习笔记我认为sleep()/usleep()/nanosleep()只能出现在测试代码中,比如写单元测试的时候(备注:设计时间的单元测试不那么好写,短的如一两秒可以用sleep();长的如一小时、一天,则得想其他办法,比如把算法提取出来并把时间注入进去)或者用于有意延长临界区,加速复现死锁的情况,就像“前文介绍的死锁”示范的那样sleep不具备memory barrier语义,它不能保证内存的可见性(参阅后面“C++多线程系统编程精要”的文章最开始的例子)生产代码中线程的等待可分为两.

2021-01-30 17:11:30 167

原创 muduo库学习之线程同步03——不要用读写锁和信号量

东阳的学习笔记文章目录不要使用读写锁不要使用信号量不要使用读写锁读写锁并不像它看上去那样那么美妙!从正确性方面来说,一种典型的易犯错误是在持有 read lock 的时候修改了共享数据。这通常发生在程序的维护阶段。程序员不小心在原来read lock保护的函数中调用了会修改状态的函数从性能方面来说,读写锁不见得比普通的 mutex_ 更高效。因为它要更新 reader 的数目。如果临界区很小,锁竞争不激烈,那么 mutex 往往会更快。在多线程编程中我们总是设法缩短临界区read.

2021-01-30 17:02:41 414

原创 muduo库学习之线程同步02——条件变量

东阳的学习笔记文章目录对于wait端:对于 signal/broadcast 端如果要等待某个条件成立,我们必须使用条件变量(condition variable)。条件变量顾名思义是一个或者多个线程等待某个布尔表达式为真,即等待别的线程唤醒它。条件变量的学名叫管程。Java Object 中内置的 wait()、notify()、notifyAll()是条件变量。条件变量只有一种正确使用的方式,几乎不可能用错。对于wait端:必须与 mutex 一起使用,该布尔表达式的读写受此 mutex.

2021-01-30 16:30:26 220

原创 muduo库学习之线程同步01——互斥器mutex

东阳的学习笔记互斥器保护了临界区,任何时刻最多只有一个线程在此 mutex 划出的临界区内活动。单独使用 mutex 时,我们主要是为了保护共享数据。下面是使用 mutex 时的一些经验和原则:主要原则有:用RAII手法封装 mutex 的创建、销毁、加锁、解锁这四个操作。只使用非递归的 mutex (即不可重入的 mutex)不手动调用 lock() 和 unlock() 函数,一切交给栈上对象 GUARD 的构造和析构函数来完成在每次构造 GUARD 对象的时候,思考调用栈上已经持有.

2021-01-30 15:07:47 302

原创 enable_shared_from_this详解

东阳的学习笔记shared_from_this()是C++多线程编程中经常会使用的到的一种方法。问题提出:见 linux 多线程服务器编程 P23. 如果 StockFactory 的生命期比 Stock 短,那么下列语句就会 core dump// ...pStock.reset(new Stock(key), boost::bind(&StockFactory::deleteStock, this, _1));// ...为了解.

2021-01-29 17:36:26 692

原创 IO复用——poll函数

东阳的学习笔记poll提供的功能和 select 类似,不过在处理流设备时,它能提供额外的信息。#include <poll.h>int poll(struct pollfd *fdarray, unsigned long nfds, int timeout);第一个参数时指向一个结构数组第一个元素的指针。每个数组元素都是一个pollfd结构,用于指定测试某个给定描述符fd的条件。struct pollfd{ int fd; /* descriptor to .

2021-01-26 13:05:06 326

原创 I/O复用——select函数详解

东阳的学习笔记select函数允许进程指示内核等待多个事件中的任何一个发生,并且只在有一个或多个事件发生或经历一段指定的时间后唤醒它。例如:我们可以调用 select,告知内核对哪些描述符(就读、写或异常条件)感兴趣或等待多长时间。集合{1, 4, 5}中的任何描述符准备好读;集合{2, 7} 中的任何描述符准备好写;集合{1, 4} 中的任何描述符有异常条件待处理;我们感兴趣的描述符不局限于套接字,任何描述符都可以用 select 来测试/* According to POSIX.1.

2021-01-25 20:55:21 253

转载 常见的5种I/O模型

学习地址:https://www.cnblogs.com/xiaoxi/p/6525396.html在《Unix网络编程》一书中提到了五种IO模型,分别是:阻塞IO、非阻塞IO、多路复用IO、信号驱动IO以及异步IO。1、阻塞IO模型最传统的一种IO模型,即在读写数据过程中会发生阻塞现象。当用户线程发出IO请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除b

2021-01-20 20:58:40 861

原创 linux gcc编译时出现 “undefined reference” 错误解决——编译muduo库错误解决

东阳的学习笔记总的来说,这个报错的意思就是说,编译器发现了一个函数的声明,但是却没有找到它的定义。我们需要将这些缺失的定义代码手动添加,来让编译器知道。把链接库作为一般的目标文件,为 GCC 指定该链接库的完整路径与文件名。解决办法如下(3选1即可)如果链接库名为 libmuduo_base.a,并且位于 /usr/lib 目录,那么下面的命令会让 GCC 编译 main.c,然后将 libmuduo_base.a 链接到 main.o:gcc main.c -o main.out /h.

2021-01-19 13:13:41 2074 1

原创 C++空间配置器 Allocator

东阳的学习笔记空间配置器代表一种特定的内存模型,并提供一种抽象概念,以便将对内存的申请最终转化为对内存的直接调用。应用程序开发者如何使用配置器就应用程序员来说,只需要传入一个 template 参数就可以了。程序库开发者如何使用配置器配置器提供了一个接口,包括分配、生成、销毁和回收对象。a.allocate(num) 为 num 个元素分配内存b.construct§ 将 p 所指的元素初始化destroy§ .

2021-01-15 13:21:56 262

原创 C++ Stream Classes 之 Stream Buffer Classes

东阳的学习笔记stream 并不负责实际的读写操作, 而是委托给 stream buffer 完成从使用者的角度看 Stream 缓冲区对于 stream 的使用者来说,class basic_streambuf 只是发送、提取字符的地方。streambuf定义了两个public函数,用来写入字符:sputc© 将字符 c 送入 stream 缓冲区 如果发生错误,返回eofsputn(s, n) 将字符序列 s 中的 n 个字符送入 stream 缓.

2021-01-15 12:50:09 451

原创 C++Stream Classes详解

东阳的学习记录基本概念Stream 类别class istream ;用来读数据class ostream :用来写数据全局性的 Stream 对象IOStream定义了数个型别为 istream 和 ostream的全局对象,它们对应于标准的 I/O 通道(channels):cin:标准输入通道,对应C stdin。操作系统通常将它和键盘连接cout:标准输出通道,对应C stdout。操作系统通常将它和监视器连接cerr:标准错误输出通道,对应C stderr。无缓冲装置.

2021-01-14 21:54:37 1092

转载 转载:C++ STL排序算法

东阳的学习笔记原文链接:https://www.cnblogs.com/cloudplankroader/p/10434931.html在介绍排序算法前,先说明一个可以称为排序准则的东西,也就是定义strict weak ordering,其意义如下:1.必须是非对称的,对operator < 而言,如果x<y是true,则y<x为false。对判断式op()而言,若op(x,y)为true,则op(x,y)为false。2.必须是可传递的,对operator < 而言,.

2021-01-14 16:26:23 265

原创 C++之仿函数与配接器bind

东阳的学习笔记所谓仿函数,是一个定义了 operator()的对象。仿函数的三大妙处仿函数比一般函数更灵巧,因为它可以拥有状态每个仿函数都有其类别。因此你可以将仿函数作为 template 参数来传递,从而指定某种行为模式。此外还有一个好处:容器类别也会因为仿函数的不同而不同仿函数的执行速度比函数指针更快一个拥有内部状态的仿函数例子如果要保存状态,则需以reference传递参数, 或者使用 for_each 的返回值(没错,for_each返回操作)./* * genera2..

2021-01-14 16:16:19 212

原创 C++ 中逆向迭代器详解

C++中逆向迭代器C++的设计者在设计逆向迭代器时运用了一个小技巧:他们实际上倒置了“半开原则”。逆向迭代器所定义的区间,实际上并不包括起点,反倒是包括了终点。而逻辑上的行为却一如常态,原因是:逻辑上所指的元素为迭代器所指位置的下一个位置,如下图:逆向迭代器做逆序处理/* * reviter4.cpp * * Created on: 2021年1月9日 * Author: san *//* * 使用逆向迭代器,将两个迭代器所指区间作逆序输出 * 使用base() 将逆

2021-01-09 20:07:27 1001

原创 C++中各种容器的选择

c++ 标准容器库提供了各具特长的不同容器 该如何选择最佳的容器?vector: 缺省情况下应该使用vector vector的内部结构最简单,并且允许随机存储,所以存储数据非常方便灵活,数据处理也很快deque: 如果经常在序列头部和尾部安插和移除元素,应该采用deque。如果你希望元素被移除时,容器内存能自动缩减,那么应该使用deque 。此外vector通常使用一个内存区块存放元素,deque采用多个区块,所以可以包含更多的元素list: 如果经常在容器中段操作元素移动,删除,安插,

2021-01-09 19:51:46 545 1

原创 STL扩展——编写自己的 STL 容器

东阳的学习笔记你可以使用字符串或数组作为 STL 容器, 也可以自行撰写特殊容器以满足特殊需求。如果你自行撰写容器, 仍可从诸如排序、合并算法中受益。此即 开放型封闭原则。将自定义的容器 “STL化” 的三种不同方法The invasive approach (侵入式作法)直接提供 STL 容器的所需接口。 这种做法需要以特定方式编写容器,所以是侵入性的。The noninvasive approach (非侵入式作法)由你撰写或提供特殊的迭代器, 作为算法和特殊容器间的界面。他需要的只是 .

2021-01-08 20:39:30 431

原创 effective c++ 09 —— 杂项讨论

东阳的学习记录条款53:不要轻忽编译器的警告严肃对待编译器发出的任何警告,争取做到没有任何警告不要依赖编译器的报警能力,不同编译器对待事情的态度并不相同条款54:让自己熟悉 TR1 在内的标准库程序https://blog.youkuaiyun.com/unirrrrr/article/details/81713132条款55:让自己熟悉BoostBoost是一个社群,致力于免费、源码开放,同僚复审的C++标准程序库开发Boost提供许多 TR1 组件实现品,以及其他许多程序库...

2021-01-05 13:52:27 183

原创 effective c++ 08 ——定制 new/delete

东阳的学习笔记多线程环境下的内存管理遭受单线程系统不曾有过的挑战。STL所使用的heap内存是由容器所拥有的分配器对象(allocator objects)管理条款49:了解new-handler的行为当operator new 抛出异常以反映一个未获满足的内存需求之前,它会先调用一个客户指定的错误处理函数,一个所谓的 new-handler。为了指定这个 “用以处理内存不足的”函数,客户必须调用 set_new_handler,其声明于头文件 。namespace std { .

2021-01-05 13:44:00 197

原创 effective c++ 07 ——模板与泛型编程

东阳的学习记录模板元编程:在C++编译期内执行并于编译完成时停止执行的程序。条款41:了解隐式接口和编译期多态面向对象(classes)总是以显示接口和运行期多态解决问题templates 接口是隐式的。多态通过 templates 具现化 和函数重载解析发生于编译期条款42:了解 typename 的双重意义声明 templates 参数时,class 与 typename 一模一样接受一个STL为参数的模板 func 无法通过编译C++假定域名作用符不是类型,必须使用typen.

2021-01-05 10:52:27 178

原创 effective c++ 06 --继承与面向对象设计

东阳的学习记录条款32:确定你的public继承塑模出 “is-a”关系正方形并不是矩形“is-a”意味着:适用于base class 身上的每一件事情也一定适用于 derived class 。条款33:避免遮掩继承而来的名称如果你正在使用 public 继承,又不继承那些重载函数,就是违反了 is-a适用using声明,使得 base 的函数可见在private继承下,是可以不满足 is-a 关系的使用 转交函数 继承某个特定版本条款34:区分接口继承与实现继承缺省的 .

2021-01-04 21:12:31 121

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除