文章 12
评论 4
浏览 32306
C++高性能服务端编程——muduo网络库源码阅读(四)TcpConnection类

C++高性能服务端编程——muduo网络库源码阅读(四)TcpConnection类

概述 前面几篇文章讲了muduo的事件驱动循环模型以及相关的实现与优化,它们是muduo网络库实现高并发和高吞吐量的基础,但这都没有涉及到网络编程相关的内容,这篇文章开始我们从muduo的TcpConnection类入手,探讨muduo网络部分的实现。 网络编程中的高性能IO实现探讨 在分析TcpConnection类的源码前,我们先来简单探讨下网络编程中如何最大化CPU资源的利用率,保证高并发场景下的吞吐率。在Linux系统中,用户对某个文件进行的IO操作是分两个阶段的,以读数据为例,用户程序调用read系统调用时,系统的行为包括:(1)等待数据准备好,数据会被拷贝到内核的缓冲区中。(2)数据准备完毕后,内核会将数据从内核缓冲区拷贝到用户空间。这个过程涉及到同步异步、阻塞非阻塞的概念 同步和非同步:所谓同步IO是指当用户进程触发IO操作时会原地等待或轮询查看数据是否就绪,一旦就绪则对数据进行内核空间和用户空间之间的拷贝,用户进程同样需要等待这个过程完成,而异步IO则是进程触发IO操作后就去做其他事情,由内核完成整个IO操作并通知进程。换句话说,同步IO是一种顺序操作,用户进程需要等....

C++高性能服务端编程——muduo网络库源码阅读(三)多线程模型

C++高性能服务端编程——muduo网络库源码阅读(三)多线程模型

概述 前面两篇文章简要分析了muduo中文件描述符的管理以及事件的注册和响应机制,通过这两篇文章的介绍可以大致勾勒出一个基本的事件循环模型,利用muduo编写的网络程序都基于这一模型驱动。当然,高性能网络库必然少不了对多线程的支持,本文就来探讨一下muduo中的多线程模型。 One loop per thread模型 关于并发网络服务程序的设计方案有多种,并且绝大部分都有它们的应用场景,《muduo》书中有一节专门介绍了常见的11种并发网络程序设计方案,并且比较了这几种方案的特点和优劣。muduo使用的多线程模型是“one loop per thread”,关于这种模式的特点,这里摘抄一段陈硕博客中的介绍 此种模型下,程序里的每个 IO 线程有一个 event loop (或者叫 Reactor),用于处理读写和定时事件(无论周期性的还是单次的),代码框架跟第 2 节一样。 这种方式的好处是: 线程数目基本固定,可以在程序启动的时候设置,不会频繁创建与销毁。 可以很方便地在线程间调配负载。 event loop 代表了线程的主循环,需要让哪个线程干活,就把 timer 或 IO ....

C++高性能服务端编程——muduo网络库源码阅读(二)事件响应与任务管理

C++高性能服务端编程——muduo网络库源码阅读(二)事件响应与任务管理

概述 上一篇文章简要介绍了reactor事件驱动模型和muduo网络库的总体架构,并且简述了事件循环核心类EventLoop的整体执行逻辑。容易看出,loop函数中 poller_对象的 poll方法和Channel的 handleEvent方法是我们需要重点关注的对象,它们分别对应对事件响应和处理的代码实现。除此以外,EventLoop中任务队列的管理和线程安全的细节也是我们需要关注的。本文将结合相关的源码,对muduo的事件响应、处理以及任务管理机制做一个分析。 muduo的IO多路复用机制 muduo实现了Linux中poll和epoll两种IO多路复用机制,同时用了一些额外的数据结构对其进行封装,以配合muduo的整体逻辑实现。在muduo中,Poller和Channel两个类是实现该机制的关键。 Channel 前面已经提过,muduo中Channel类相当于上一篇文章reactor模型中的handler,每个文件描述符都对应一个Channel,由它负责注册对应事件的回调函数。需要注意的是,Channel并不拥有这个文件描述符,只是拥有文件描述符的事件信息和回调逻辑。换句话说....

C++高性能服务端编程——muduo网络库源码阅读(一)基础结构与事件驱动循环

C++高性能服务端编程——muduo网络库源码阅读(一)基础结构与事件驱动循环

简介 muduo是陈硕编写的一个基于非阻塞IO和事件驱动设计的C++网络编程库,基于Reactor模式设计,原生支持多核多线程模式,其网络部分并不具备十分复杂的功能,并且仅支持Linux系统。作为一个功能相对简单且性能不俗的网络编程库,muduo非常适合作为C++网络编程新手的入门练习项目。本系列博客结合陈硕所著《Linux多线程服务端编程:使用muduo C++网络库》(后文统称《muduo》)以及muduo源码,探讨我对muduo网络库源码的理解及服务端事件驱动模型设计的总结。 事件驱动模型 多线程服务器模型中,一个很自然的想法是在程序中维护一个线程池,每当有新的连接请求到达时,便为其分配一个线程单独处理其IO请求。这种模型虽然直观,但它仅适用于并发访问量不大的场景,随着并发需求的增加,系统在线程切换间的开销就会急剧增加,并且线程在等待IO时不能去做其他事情,会造成CPU资源的浪费。为了提高服务端的处理效率和吞吐量,大多数服务端设计采用事件驱动模型,将事件的响应与处理分离。其中,IO多路复用机制是实现事件驱动模型的关键。 Reactor模型是一种重要的事件驱动模型,除了本文介绍的m....

关于C++智能指针的一些思考和总结

关于C++智能指针的一些思考和总结

简介   在C++语言的编程中,内存是一个非常重要的概念,其原因在于C++不像其他的高级语言(如java, python, go等)一样提供了内存回收机制,编程过程中在堆内存区域上申请的所有内存都必须手动管理和释放,管理不当的话极容易造成内存泄漏。在C++中,我们一般使用new操作符在堆上申请内存,如 std::string* p = new std::string("hello world"); 这个语句使用new操作符在堆内存上构建了一个字符串对象,new操作符会返回一个指针供程序访问这个对象。需要注意的是,指针p是我们访问这个对象所在内存区域的唯一途径,当不需要使用这个对象时,应当使用delete操作符释放内存,即 delete p; 在后面的程序中,大致有三种情况会造成内存泄漏:1)某个线程修改了指针p的值而没有释放内存;2)程序在delete之前抛出异常,导致没有成功执行delete;3)p指针存在于栈内存上,离开指针所处的作用域时没有返回p的值,这时指针p被释放导致我们丢失了该字符串对象的内存地址。   内存泄漏在C++程序中是一种危害性较大但又经常出现的问题,因为我们....

Everything that kills me makes me feel alive