当前位置: 首页 > news >正文

6. C++通过fork的方式实现高性能网络服务器

我们上一节课写的tcp我们发现只有第一个与之连接的人才能收发信息。他又很多的不足

高性能网络服务器

  • 通过fork实现高性能网络服务器
    我们通过fork进行改装之后就可以成百上千的用户进行连接访问,对于每一个用户来说我们都fork一个子进程。让后让每一个子进程都是与服务器端的一个对应关系。这样并行的进行处理。但是还是有很多的不足之处。
  • 通过select实现高性能网络服务器
    通过IO复用的方式来实现多个客户端与服务器端进行通信。
  • 通过epoll实现高性能网络服务器
    也是通过IO复用的方式来实现多个客户端与服务器端进行通信,但是他比select更加高效。它通过底层内核级事件,更高校
  • 利用I/O事件处理库来实现高性能网络服务器

以fork方式实现高性能网络服务器

一个主进程进行监听连接。每收到一个连接就创一个子进程,多个子进程进行并行连接。然后父进程负责接收连接,通过fork创建子进程。
头文件

#include <sys/types.h>
#include <unistd.h>

原型

pid_t fork(void);

fork()是一个系统调用函数,用于在 Unix-like 操作系统中创建一个新的进程。它会复制当前进程(称为父进程),并在新的进程(称为子进程)中继续执行。
fork()函数返回的是一个 pid_t 类型的值,pid是进程id,如果pid==0,说明是子进程,如果大于0就是父进程。其含义如下:

  • 在父进程中,fork() 返回新创建的子进程的进程 ID(PID)。
  • 在子进程中,fork() 返回 0。
  • 如果创建子进程失败,fork() 返回 -1。

fork() 函数在创建子进程时会返回两次,这是因为它是一个复制当前进程的系统调用。具体来说,fork() 函数会创建一个新的进程(子进程),并将父进程的所有内容(包括代码、数据、堆栈等)复制到子进程中。
第一次返回:

  • 在父进程中,fork() 返回新创建的子进程的进程 ID(PID)。
  • 如果创建子进程失败,fork() 返回 -1。

第二次返回:

  • 在子进程中,fork() 返回 0。
  • 通过这两次返回,父进程和子进程可以根据不同的返回值采取不同的逻辑分支。

在父进程中,可以根据返回的子进程 PID 做一些与子进程相关的操作,如记录子进程的 PID、等待子进程的终止等。
在子进程中,由于 fork() 返回的是 0,可以根据此特性来区分自己是子进程,从而执行特定的子进程代码逻辑。
需要注意的是,父进程和子进程会继续执行 fork() 调用之后的代码,并且它们是在不同的进程上下文中运行的,拥有各自独立的内存空间和资源。因此,在使用 fork() 创建子进程时,通常需要在父子进程中进行不同的处理,以避免竞态条件和不必要的资源共享问题。

这个代码还是在服务器端,接收客户端的时候fork一个子线程。然后进行通信。
tcp_server_fork.cpp

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream>//端口
#define PORT 8888
#define MESSAGE_LEN 1024int main(int argc,char* argv[]){int ret=-1;int on=1;int backlog=10;//缓冲区大小int socket_fd,accept_fd;pid_t pid;struct sockaddr_in localaddr,remoteaddr;char in_buff[MESSAGE_LEN]={0,};socket_fd=socket(AF_INET,SOCK_STREAM,0);if(socket_fd==-1){std::cout<<"Failed to create socket!"<<std::endl;exit(-1);}ret=setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));if(ret==-1){std::cout<<"Failed to set socket options!"<<std::endl;}localaddr.sin_family=AF_INET;//地址族localaddr.sin_port=htons(PORT);//端口号localaddr.sin_addr.s_addr=INADDR_ANY;//这个就是0bzero(&(localaddr.sin_zero), 8);ret= bind(socket_fd,(struct sockaddr *)&localaddr,sizeof(struct sockaddr));//绑定if(ret==-1){//绑定失败std::cout<<"Failed to bind addr!"<<std::endl;exit(-1);}ret = listen(socket_fd,backlog);//第二个是缓冲区大小,因为同一时间只能处理一个,其他都放在缓冲区if(ret==-1){std::cout<<"failed to listen socket!"<<std::endl;exit(-1);}while(1){//等待连接socklen_t addr_len=sizeof(struct sockaddr);accept_fd = accept(socket_fd,(struct sockaddr *)&remoteaddr,&addr_len);//每次接收之后我们fork一个子进程。pid是进程id,如果pid==0,说明是子进程,如果大于0就是父进程pid = fork();if(pid == 0){//连接了while(1){//这个是连接了之后,发消息memset(in_buff, 0, sizeof(in_buff));//接收消息ret = recv(accept_fd,(void *)in_buff,MESSAGE_LEN,0);if(ret==0){break;}std::cout<<"recv:"<<in_buff<<std::endl;//返回消息send(accept_fd,(void*)in_buff,MESSAGE_LEN,0);}}close(accept_fd);}if(pid!=0){close(socket_fd);}return 0;
}

clang++ -g -o tcp_server_fork tcp_server_fork.cpp
./tcp_server_fork

客户端还是上个文章的客户端。

fork()的优缺点

使用 fork() 函数创建子进程的服务器有以下优点和缺点:
优点:
简单易用:使用 fork() 函数创建子进程的服务器相对简单,不需要使用复杂的多线程或多进程编程模型。通过复制父进程的内存空间,子进程可以独立运行,处理客户端请求。
高并发处理:每个客户端连接都可以创建一个独立的子进程,这样服务器能够同时处理多个客户端请求,实现高并发性能。
数据共享:父进程和子进程共享文件描述符,可以轻松共享一些资源和状态信息,例如打开的文件、缓冲区等。
可靠性:由于每个子进程是独立运行的,一个子进程的崩溃或异常不会影响其他子进程或主服务器进程。

缺点:
内存开销:每个子进程都需要复制父进程的内存空间,因此在大规模并发的情况下,服务器的内存开销会比较大。
进程切换开销:由于每个客户端连接都需要创建子进程,因此涉及到进程之间的切换开销,包括上下文切换和进程间通信开销,这可能对服务器性能产生一定的影响。
可伸缩性:由于每个客户端连接都需要创建子进程,服务器的可伸缩性可能受到限制。在大规模并发情况下,为每个连接创建子进程可能会导致系统资源耗尽。
进程间通信复杂性:如果子进程之间需要进行通信或共享数据,就需要使用进程间通信(IPC)机制,如管道、共享内存等。这增加了编程的复杂性。
    综上所述,使用 fork() 函数创建子进程的服务器适用于简单的并发场景和较小规模的应用,但在大规模高并发、资源消耗较大或需要更高可伸缩性的情况下,可能需要考虑其他并发模型,如多线程或事件驱动模型。

参考:https://blog.csdn.net/lepaitianshi/article/details/132981657

相关文章:

6. C++通过fork的方式实现高性能网络服务器

我们上一节课写的tcp我们发现只有第一个与之连接的人才能收发信息。他又很多的不足 高性能网络服务器 通过fork实现高性能网络服务器 我们通过fork进行改装之后就可以成百上千的用户进行连接访问&#xff0c;对于每一个用户来说我们都fork一个子进程。让后让每一个子进程都是…...

直播美颜插件、美颜SDK详解:技术、功能与实现原理

今天&#xff0c;小编将详细解析直播美颜插件和美颜SDK的技术、功能以及实现原理。 一、美颜技术的背景与发展 1.1美颜技术的兴起 随着直播平台的普及&#xff0c;美颜SDK技术逐渐被集成到直播软件中&#xff0c;以满足用户对更美观、自然的直播效果的需求。 1.2美颜技术的…...

MyBatis入门(1)

目录 一、JDBC操作回顾 二、什么是MyBatis&#xff1f; 三、MyBatis入门 1、准备工作 &#xff08;1&#xff09;创建工程 &#xff08;2&#xff09;数据准备 2、配置数据库连接字符串 3、写持久层代码 4、单元测试 &#xff08;1&#xff09;使用IDEA自动成成测试类…...

打开服务器远程桌面连接不上,可能的原因及相应的解决策略

在解决远程桌面连接不上服务器的问题时&#xff0c;我们首先需要从专业的角度对可能的原因进行深入分析&#xff0c;并据此提出针对性的解决方案。以下是一些可能的原因及相应的解决策略&#xff1a; 一、网络连接问题 远程桌面连接需要稳定的网络支持&#xff0c;如果网络连接…...

用于时间序列概率预测的蒙特卡洛模拟

大家好&#xff0c;蒙特卡洛模拟是一种广泛应用于各个领域的计算技术&#xff0c;它通过从概率分布中随机抽取大量样本&#xff0c;并对结果进行统计分析&#xff0c;从而模拟复杂系统的行为。这种技术具有很强的适用性&#xff0c;在金融建模、工程设计、物理模拟、运筹优化以…...

VScode解决报错“Remote-SSH XHR failed无法访问远程服务器“的方案

VScode解决报错"Remote-SSH XHR failed无法访问远程服务器"的方案 $ ls ~/.vscode-server/bin 2ccd690cbff1569e4a83d7c43d45101f817401dc稳定版下载链接&#xff1a;https://update.code.visualstudio.com/commit:COMMIT_ID/server-linux-x64/stable 内测版下载链接…...

Python高级进阶--dict字典

dict字典⭐⭐ 1. 字典简介 dictionary&#xff08;字典&#xff09; 是 除列表以外 Python 之中 最灵活 的数据类型&#xff0c;类型为dict 字典同样可以用来存储多个数据字典使用键值对存储数据 2. 字典的定义 字典用{}定义键值对之间使用,分隔键和值之间使用:分隔 d {中…...

记忆力和人才测评,如何提升记忆力?

什么是记忆力&#xff1f; 如何通俗意义上的记忆力&#xff1f;我们可以把人的经历、经验理解成为一部纪录片&#xff0c;那么已经过去发生的事情&#xff0c;就是影片之前的情节&#xff0c;对于这些信息&#xff0c;在脑海里&#xff0c;人们会将其进行处理和组合&#xff…...

数据仓库建模

目录 数仓建模 为什么要对数据仓库进行分层 主题 主题的概念 维度建模&#xff1a; 模型的选择&#xff1a; 星形模式 雪花模型 星座模式 拉链表 维度表和事实表&#xff1a; 维度表 事实表 事实表设计规则 退化维度 事务事实表、周期快照事实表、累积快照事实…...

力扣:1738. 找出第 K 大的异或坐标值

1738. 找出第 K 大的异或坐标值 给你一个二维矩阵 matrix 和一个整数 k &#xff0c;矩阵大小为 m x n 由非负整数组成。 矩阵中坐标 (a, b) 的 值 可由对所有满足 0 < i < a < m 且 0 < j < b < n 的元素 matrix[i][j]&#xff08;下标从 0 开始计数&…...

Keras深度学习框架第二十讲:使用KerasCV中的Stable Diffusion进行高性能图像生成

1、绪论 1.1 概念 为便于后文讨论&#xff0c;首先进行相关概念的陈述。 Stable Diffusion&#xff1a;Stable Diffusion 是一个在图像生成领域广泛使用的技术&#xff0c;尤其是用于文本到图像的转换。它基于扩散模型&#xff08;Diffusion Models&#xff09;&#xff0c;这…...

C/C++ vector详解

要想了解STL&#xff0c;就必须会看&#xff1a; cplusplus.comhttps://legacy.cplusplus.com/ 官方内容全都是英文的&#xff0c;可以参考&#xff1a; C/C初始识https://blog.csdn.net/2301_77087344/article/details/138596294?spm1001.2014.3001.5501 vector&#xff…...

使用libtorch加载YOLOv8生成的torchscript文件进行目标检测

在网上下载了60多幅包含西瓜和冬瓜的图像组成melon数据集&#xff0c;使用 LabelMe 工具进行标注&#xff0c;然后使用 labelme2yolov8 脚本将json文件转换成YOLOv8支持的.txt文件&#xff0c;并自动生成YOLOv8支持的目录结构&#xff0c;包括melon.yaml文件&#xff0c;其内容…...

Oracle 并行和 session 数量的

这也就是为什么我们指定parallel为4&#xff0c;而实际并行度为8的原因。 insert create index&#xff0c;发现并行数都是加倍的 Indexes seem always created with parallel degree 1 during import as seen from a sqlfile. The sql file shows content like: CREATE INDE…...

Android 版本与 API level 以及 NDK 版本对应

采用 Android studio 开发 Android app 的时候&#xff0c;需要选择支持的最低 API Level 和使用的 NDK 版本&#xff0c;对应开发 app 的最低 SDK 版本&#xff1a; 在 app 的 build.gradle 文件里&#xff0c;对应于代码如下&#xff1a; 目前各版本的占有率情况如下&#xf…...

护网经验面试题目原版

文章目录 一、护网项目经验1.项目经验**Hvv的分组和流程**有没有遇到过有意思的逻辑漏洞&#xff1f;有没有自己开发过武器/工具&#xff1f;有做过代码审计吗&#xff1f;有0day吗有cve/cnvd吗&#xff1f;有src排名吗&#xff1f;有没有写过技战法有钓鱼经历吗&#xff1f;具…...

ipa 覆盖算法测试

相关文章 ipa 功能包测试 ipa 分区算法 ipa 分区算法总结&#xff0c;部分算法图解 ipa 覆盖算法分析&#xff08;一&#xff09; ipa 覆盖算法分析&#xff08;二&#xff09; 测试 网上找的地图&#xff1a; fig.1 测试地图 opencv fig.2 opencv 显示的覆盖路径 rviz fi…...

linuxwindows硬件信息midecod和wmic命令

1、命令dmidecode -t实例 1.1命令格式 dmidecode -t [类型代码或名称 ] 指令 1.2获取系统信息 [rootlala docker]# dmidecode -t 1 1.3获取主板信息&#xff1a; [rootshanghai docker]# dmidecode -t 2 1.4获取CPU ID dmidecode -t 4 | grep ID 1.5获取系统序列号 …...

03. SpringBoot 整合 Redis

文章目录 Jedis导入依赖测试连接Jedis 实现事务 SpringBoot 整合 RedisRedisTemplateSpringBoot 整合 Redis 测试RedisTemplate 序列化RedisUtils Jedis Jedis 是 Redis 官方推荐的 Java 连接工具。 导入依赖 </dependencies><dependency><groupId>redis.c…...

01-Linux【准备篇】

一、学Linux的作用&#xff1f; 1.Linux下开发(部署)软件项目 2.Linux运维 二、Linux的强与弱 1.薄弱 个人桌面领域的应用 此领域是传统Linux应用薄弱的环节&#xff0c;近些年随着Ubuntu、fedora等优秀桌面环境的兴起&#xff0c;Linux在个人桌面领域的占有率在慢慢提高…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...