Linux高性能服务器编程 12. 多线程编程
12. 多线程编程06-线程概念_哔哩哔哩_bilibili 早期Linux不支持线程,直到1996年,Xavier Leroy等人开发出第一个基本符合POSIX标准的线程库LinuxThreads,但LinuxThreads效率低且问题多,自内核2.6开始,Linux才开始提供内核级的线程支持,并有两个组织致力于编写新的线程库:NGPT(Next Generation POSIX Threads)和NPTL(Native POSIX Thread Library),但前者在2003年就放弃了,因此新的线程库就是NPTL。NPTL比LinuxThreads效率高,且更符合POSIX规范,所以它已经成为glibc的一部分,本书使用的线程库是NPTL。 本章要讨论的线程相关的内容都属于POSIX线程(简称 pthread)标准,不局限于NPTL实现,包括: 创建线程和结束线程; 读取和设置线程属性; POSIX线程同步方式:POSIX信号量、互斥锁和条件变量。 1.线程概念1.什么是线程**LWP:**light weight process...
Linux高性能服务器编程 信号 信号量 条件变量三者辨析
信号,信号量,条件变量三者辨析1.信号(Signal) 概念 信号是一种软中断机制,用于通知进程发生了某个特定的事件。它是一种异步事件通知方式,进程在收到信号时可以采取相应的动作,如终止进程、暂停进程或者忽略信号等。信号是由操作系统内核发送给进程的。 举例 当用户在终端中按下Ctrl + C组合键时,内核会向当前正在运行的前台进程发送一个SIGINT(中断信号)。如果进程没有对这个信号进行特殊处理,默认情况下会终止运行。例如,下面是一个简单的 C 程序来处理SIGINT信号: 123456789101112131415161718192021#include <stdio.h>#include <signal.h>#include <stdlib.h>void signal_handler(int signum) { printf("Received signal %d\n", signum); // 在这里可以进行更复杂的处理,比如清理资源等}int main() { ...
Linux高性能服务器编程 10. 高性能I/O框架库Libevent
10. 高性能I/O框架库LibeventLinux服务器程序必须处理三类事件(I/O、信号和定时事件),在处理这三类事件时需要考虑以下问题: **统一事件源。**统一处理这三类事件既能使代码简单易懂,又能避免一些潜在的逻辑错误。实现统一事件源的一般方法:利用 I/O复用系统调用来管理所有事件。 **可移植性。**不同的操作系统有不同的I/O复用方式,如Solaris的dev/poll文件、FreeBSD的kqueue机制、Linux的epoll系列系统调用。 **对并发编程的支持。**在多进程和多线程环境下,我们需要考虑各执行实体如何协同处理客户连接、信号、定时器,以避免竞态条件。 开源社区提供了很多优秀的开源I/O框架库,它们不仅解决了以上问题,让开发者可以将精力完全放在程序的逻辑上,而且稳定性、性能等各方面都相当出色,如ACE、ASIO 和...
Linux高性能服务器编程 10. 高性能I/O框架库Libevent
Ubuntu安装libevent库Libevent是一个高性能事件通知库,它在网络编程中非常有用。它可以用于开发各种网络应用程序,包括服务器和客户端。在本篇博客中,我们将介绍如何在Linux系统上安装libevent库,以便你可以开始编写高性能的网络应用程序。 1.准备工作在开始安装libevent之前,确保你的Linux系统已经安装了以下工具和库: gcc编译器 make工具 2.下载libevent你可以从libevent的官方网站(https://libevent.org/)下载最新版本的libevent。在终端中,使用`wget`命令下载libevent的源代码压缩包: wget https://github.com/libevent/libevent/releases/download/release-2.1.12-stable/libevent-2.1.12-stable.tar.gz 也可以下载好安装包用XFTP传输过去 3.解压并编译libevent解压下载的libevent源代码: 1tar zxvf...
Linux高性能服务器编程 Libevent实现TCP客户端服务器
Libevent实现TCP客户端服务器17-libevent实现Tcp服务器流程_bilibili_哔哩哔哩_bilibili 1.服务器端实现流程1.创建 event_base 2.创建服务器连接监听器 evconnlister_new_bind() ; 3.在 evconnlister_new_bind 的回调函数中,处理接受连接后的操作 4.回调函数被调用,说明有一个新客户端连接上来。会得到一个新fd,用于跟客户端通信(读、写) 5.使用 bufferevnet_socket_new()创建一个新bufferevnet事件,将fd 封装到这个事件对象中 6.使用 bufferevent_setcb 给这个事件对象的 read、write、event 设置回调 7.设置 bufferevnet 的读写缓冲区 enable/disable 8.接受、发送数据 bufferevent_read()/bufferevent_write()...
Linux高性能服务器编程 高并发服务器
高并发服务器1.多进程并发服务器linux网络编程 | c | 多进程并发服务器实现-CSDN博客 2.多线程并发服务器linux网络编程 | c | 多线程并发服务器实现-CSDN博客 3.多路IO转接服务器1.selectlinux网络编程 | c | select实现IO多路转接服务器-CSDN博客 2.polllinux网络编程 | c | select实现IO多路转接服务器-CSDN博客 3.epolllinux网络编程 | c | epoll实现IO多路转接服务器-CSDN博客 4.libeventLibevent实现TCP客户端服务器-CSDN博客 5.UDPUDP通信-CSDN博客
Linux高性能服务器编程 7. I/O 复用
7. I/O 复用0.前情提要-IO多路转接服务器设计思路1.前情提要I/O 复用使得程序能够同时监听多个文件描述符,从而提高程序的性能。I/O 复用本身是阻塞的。Linux 下实现 I/O 复用的系统调用主要有 select、poll 和 epoll。 IO复用和多路IO复用只是表述上不同,实际上指的是同一个东西。 Reactor 模型基本原理回顾 Reactor 模型是一种事件驱动的设计模式,主要包含事件分离器(Reactor)和事件处理器(Handler)。事件分离器负责监听 I/O 事件,当事件发生时,将事件分发给相应的事件处理器进行处理。、 而本章的select,poll,epoll都是Reactor模型的一种实现方式。 select 是 Reactor 模型的一种实现方式 事件监听机制:select 函数充当事件分离器的角色。它可以同时监听多个文件描述符(包括套接字)的可读、可写和异常事件。程序将需要监听的文件描述符集合传递给 select 函数,select...
Linux高性能服务器编程 8. 信号
8. 信号信号是由用户、系统、进程发送给目标进程的信息,以通知目标进程某个状态的改变或系统异常。Linux信号可由以下条件产生: 对于前台进程,用户可通过输入特殊终端字符来给它发送信号,如输入Ctrl+C通常会给进程发送一个中断信号。 系统异常。如浮点异常或非法内存段访问。 系统状态变化。如alarm定时器到期将引起SIGALRM信号。 运行kill命令或调用kill函数。 服务器程序必须处理(或至少忽略)一些常见信号,以免异常终止。 1.Linux 信号概述0.全部信号1.信号的四要素信号使用前应确定它的四要素 编号 名称 事件 默认处理动作 2.信号的编号kill -l 获取全部信号 SIGHUP本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时, 通知同一session内的各个作业,...
Linux高性能服务器编程 9. 定时器
9. 定时器网络程序需要处理定时事件,如定期检测一个客户连接的活动状态。服务器程序通常管理着众多定时事件,有效地组织这些定时事件,使其在预期的时间被触发且不影响服务器的主要逻辑,对于服务器的性能有至关重要的影响。为此,我们要将每个定时事件分别封装成定时器,并使用某种容器类数据结构,如链表、排序链表、时间轮,将所有定时器串联起来,以实现对定时事件的统一管理。本章主要讨论两种高效的管理定时器的容器:时间轮和时间堆。 定时指在一段时间后触发某段代码的机制,我们可以在这段代码中依次处理所有到期的定时器,即定时机制是定时器得以被处理的原动力。Linux提供三种定时方法: socket套接字选项SO_RCVTIMEO和SO_SNDTIMEO; SIGALRM信号; I/O复用系统调用的超时参数。 1.socket 选项 SO_RCVTIMEO 和 SO_SNDTIMEOSO_RCVTIMEO设置 socket 接收数据超时时间。 SO_SNDTIMEO设置 socket 发送数据超时时间。 这两个数据仅对与数据接收和发送相关的 socket 系统调用...
Linux高性能服务器编程 UDP通信
UDP通信1.TCP和UDP通信优缺点 2.UDP的通信流程1.serve和client相对TCP来说, 服务端的accept()和客户端connect()不需要了 recv()和send()只能用于TCP serve端: lfd = socket(AF_INET,SOCK_DGRAM,0) 由SOCK_STREAM 改为了 SOCK_DGRAM bind(lfd,地址结构,地址结构大小) listen() – 可有可无 while(1){ read(cfd,buf,sizeof)–>被替换为–>recvfrom() write()–>被替换为–>sendto() } close() client端: confd = socket(AF_INET,SOCK_DGRAM,0) sendto(服务器的地址结构,地址结构大小) recvfrom()读回新数据 close() 2.recvfrom和sendto1ssize_t recvfrom(int sockfd, void *buf, size_t len, int...













