《Linux多线程服务端编程:使用muduo C++网络库》学习笔记,★firecat推荐★

简介: 《Linux多线程服务端编程:使用muduo C++网络库》学习笔记,★firecat推荐★

4.9 多线程与fork


fork()一般不能在多线程中调用,因为Linux的fork只克隆当前线程的thread of ctrl,不克隆其他线程。即,fork之后子进程只有一个线程,其他线程都消失了。



7.2文件传输


如果客户端故意只发起连接,不接收数据,那么要么服务器进程的文件描述符耗尽,要么占用很多服务器内存,因为每个连接会建立缓冲区。解决方法是:


1、限制服务器的最大并发连接数


2、用timing wheel踢掉空闲连接https://blog.csdn.net/Solstice/article/details/6395098


3、关于muduo时间轮的实现


muduo举的例子,使用了boost库的circular_buffer:


/boost_1_68_0/boost/circular_buffer/*.*


/boost_1_68_0/boost/circular_buffer.hpp


https://github.com/chenshuo/muduo/blob/master/examples/idleconnection/echo.h


如果想摆脱boost库的依赖,需要自己写circular_buffer,参考:


Ring Buffer (circular Buffer)环形缓冲区简介


https://github.com/AlexStocks/muduo/blob/master/muduo/other/circular_buffer.h


https://github.com/kimg-bo/kimgbo/blob/master/example/idleconnection/echo.h


linux网络编程二十二:高性能定时器之时间轮



7.4Buffer类的设计与使用https://blog.csdn.net/Solstice/article/details/6329080


/// A buffer class modeled after org.jboss.netty.buffer.ChannelBuffer

///

/// @code

/// +-------------------+------------------+------------------+

/// | prependable bytes |  readable bytes  |  writable bytes  |

/// |                   |     (CONTENT)    |                  |

/// +-------------------+------------------+------------------+

/// |                   |                  |                  |

/// 0      <=      readerIndex   <=   writerIndex    <=     size

/// @endcode



7.4.1在现实生活中,IO复用总是和非阻塞IO一起使用,因为:


基础知识:


(1)IO阻塞与否体现在read/write/accept/connect等IO函数的使用方式;有阻塞和非阻塞线程两种方式。


(2)IO复用体现在select/poll/epoll_wait等函数。这些函数会阻塞当前线程。


实际原因:


(1)没有人会真的使用轮询来检查某个非阻塞IO操作是否完成,这样太浪费CPU;


(2)IO复用一般不能和阻塞IO使用,因为阻塞IO的read/write/accept/connect函数都会阻塞当前线程。这样线程就无法处理其他的IO事件了。


(3)非阻塞IO的核心思想是避免阻塞在read/write/accept/connect等IO系统调用上,IO线程只能阻塞在IO复用函数上,如select/poll/epoll_wait等。


(4)更详细的知识,可以参考《UNP》第16章,非阻塞IO。



★为什么 non-blocking 网络编程中应用层 buffer 是必须的?


https://blog.csdn.net/libaineu2004/article/details/80555051



★C10K的问题:


《高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少》

《高性能网络编程(二):上一个10年,著名的C10K并发连接问题》

《高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了》

《高性能网络编程(四):从C10K到C10M高性能网络应用的理论探索》

《高性能网络编程经典:《The C10K problem(英文)》[附件下载]》


8.8TcpConnection发送数据


1、muduo采用epoll的LT模式(ET模式要求用户一次性把数据读完,而LT则不需要,可以先读50字节再在下一次io循环时读剩余部分),只在需要时才关注writable事件,否则会造成busy loop;


2、send函数,io线程和非io线程的区别


image.png


截图是从muduo书P318来的,书上写非io线程。我的理解是:


muduo net的线程叫io线程,one loop per thread + threadpool;参加书P174;


用户自己开的业务线程就叫非io线程,然后在业务线程调用send函数。


举例一个应用场景就是,客户端发起请求,服务器需要从redis或mysql取数据,然后send回客户端。考虑到从MySQL取数据比较耗时,不能在io线程去处理业务(否则会造成busy loop),我就另起了非io线程。所以需要在非io线程send。


说白了就是一句话,服务器这样: conn丢给了非io线程, 阻塞访问mysql, 得到响应了,调用conn->send。


非io线程建议使用线程池来实现。



8.12TcpClient

客户端连接断开后初次重试的延迟应该有随机性,比如说服务端奔溃,它所有的客户连接同时断开,然后0.5s之后再次发起连接,这样既可能造成SYN丢包,也可能给服务器带来短期大负载,影响其服务质量。因此每个客户端应该等待一段随机的时间(0.5~2s),再重试,避免拥塞。


相关文章
|
网络协议 安全 Linux
Linux C/C++之IO多路复用(select)
这篇文章主要介绍了TCP的三次握手和四次挥手过程,TCP与UDP的区别,以及如何使用select函数实现IO多路复用,包括服务器监听多个客户端连接和简单聊天室场景的应用示例。
529 0
|
存储 Linux C语言
Linux C/C++之IO多路复用(aio)
这篇文章介绍了Linux中IO多路复用技术epoll和异步IO技术aio的区别、执行过程、编程模型以及具体的编程实现方式。
907 1
Linux C/C++之IO多路复用(aio)
|
存储 编译器 Linux
动态链接的魔法:Linux下动态链接库机制探讨
本文将深入探讨Linux系统中的动态链接库机制,这其中包括但不限于全局符号介入、延迟绑定以及地址无关代码等内容。
2416 141
|
资源调度 Linux 调度
Linux c/c++之进程基础
这篇文章主要介绍了Linux下C/C++进程的基本概念、组成、模式、运行和状态,以及如何使用系统调用创建和管理进程。
281 0
|
存储 网络协议 安全
Java网络编程,多线程,IO流综合小项目一一ChatBoxes
**项目介绍**:本项目实现了一个基于TCP协议的C/S架构控制台聊天室,支持局域网内多客户端同时聊天。用户需注册并登录,用户名唯一,密码格式为字母开头加纯数字。登录后可实时聊天,服务端负责验证用户信息并转发消息。 **项目亮点**: - **C/S架构**:客户端与服务端通过TCP连接通信。 - **多线程**:采用多线程处理多个客户端的并发请求,确保实时交互。 - **IO流**:使用BufferedReader和BufferedWriter进行数据传输,确保高效稳定的通信。 - **线程安全**:通过同步代码块和锁机制保证共享数据的安全性。
675 23
|
Linux 编译器 vr&ar
Linux的动态库与静态库
静态库在编译时直接嵌入到最终的可执行文件中。
266 0
|
消息中间件 Linux C++
c++ linux通过实现独立进程之间的通信和传递字符串 demo
的进程间通信机制,适用于父子进程之间的数据传输。希望本文能帮助您更好地理解和应用Linux管道,提升开发效率。 在实际开发中,除了管道,还可以根据具体需求选择消息队列、共享内存、套接字等其他进程间通信方
441 16
|
Ubuntu Linux 编译器
Linux/Ubuntu下使用VS Code配置C/C++项目环境调用OpenCV
通过以上步骤,您已经成功在Ubuntu系统下的VS Code中配置了C/C++项目环境,并能够调用OpenCV库进行开发。请确保每一步都按照您的系统实际情况进行适当调整。
3252 3
|
并行计算 Ubuntu Linux
Ubuntu学习笔记(三):Linux下操作指令大全
Ubuntu学习笔记,介绍了Linux操作系统中常用的命令和操作,如文件管理、系统信息查看、软件安装等。
522 3
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
955 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库