Socket编程之多进程模型

news2024/12/23 23:12:34

一、多进程模型概述

        基于最初的阻塞网络 I/O ,若服务器要为多个客户端提供支持,在较为传统的手段中,多进程模型是常用的选择,即为每个客户端都分配一个进程来处理其请求。 服务器的主进程主要负责对客户连接的监听,一旦与客户端的连接成功达成,accept() 函数便会返回一个“已连接 Socket”。此时,通过 fork() 函数创建一个子进程,实际上是把父进程的所有相关内容都进行复制,涵盖了文件描述符、内存地址空间、程序计数器以及执行的代码等等。 在这两个进程刚刚完成复制的时刻,几乎毫无差异。然而,会依据返回值来辨别是父进程还是子进程。倘若返回值为 0 ,那就是子进程;要是返回值为其他的整数,那便是父进程。 正因子进程会复制父进程的文件描述符,所以能够直接运用“已连接 Socket ”与客户端进行通信。 可以看到,子进程无需关注“监听 Socket”,仅需留意“已连接 Socket”;而父进程则相反,将客户服务交由子进程处理,故而父进程不必关心“已连接 Socket”,只需重视“监听 Socket”。

下面这张图描述了从连接请求到连接建立,父进程创建生子进程为客户服务。

二、多进程模型服务端代码

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<fcntl.h>
#include<sys/socket.h>
#include<netinet/ip.h>
#include<arpa/inet.h> 

#define SERROPT 8000  // 定义服务器端口号
#define SERIP "192.168.117.127"  // 定义服务器 IP 地址

int main(int argc, char* argv[])                                                                                                                                               
{
    // 创建一个套接字 
    // socket参数:1.协议类型 2.流式套接字 3.传 0(默认 TCP 协议)
    int lfd = socket(AF_INET, SOCK_STREAM, 0);  // 创建一个 TCP 套接字,返回文件描述符 lfd
    struct sockaddr_in seraddr, cliaddr;  // 定义服务器和客户端的地址结构体
    seraddr.sin_family = AF_INET;  // 设置服务器地址结构体的协议族为 IPv4
    seraddr.sin_port = htons(SERROPT);  // 设置服务器端口号,将主机字节序转换为网络字节序
    seraddr.sin_addr.s_addr=INADDR_ANY;  // 设置服务器的 IP 地址为任意可用地址
    bind (lfd, (struct sockaddr*)&seraddr, sizeof(seraddr));  // 将套接字与服务器地址绑定
    listen(lfd,64);  // 监听套接字,设置最大等待连接数为 64
    socklen_t clilen = sizeof(cliaddr);  // 客户端地址结构体长度
    while(1)  // 无限循环,持续接受客户端连接
    {
        int scfd = accept(lfd, (struct sockaddr*)&cliaddr, &clilen);  // 接受客户端连接,返回新的套接字描述符 scfd
        int pid =fork();  // 创建子进程
        if(pid == 0)  // 如果是子进程
        {
            close(lfd);  // 关闭父进程的监听套接字
            while(1)  // 子进程中的无限循环,用于处理与客户端的通信
            {
                char buf[1024];  // 定义接收缓冲区
                int rr = read(scfd, buf, sizeof(buf));  // 从客户端读取数据到缓冲区,返回读取的字节数
                write(STDERR_FILENO, buf, rr);  // 将读取的数据写到标准错误输出
                write(scfd, buf, rr);  // 将数据反射回客户端,证明客户端已接收
            }
        }
    }
    return 0;      
} 

Ip地址换成自己虚拟机Ip地址,运行服务器再创建一个终端输入命令(nc  你的ip地址  你设置的端口号)就可以连接到服务器进行通讯。

三、多进程模型注意事项及不足

注意事项:

  • 当子进程结束运行并退出后,尽管它不再处于活动状态,但内核仍会保留一些关于它的基本信息,比如进程的退出状态等。这些保留的信息会占用一定的内存空间,如果父进程不及时进行回收处理,子进程就会变成僵尸进程。僵尸进程持续累积会不断消耗系统的内存等资源,最终可能导致系统资源匮乏,影响整个系统的正常运行。
  • 为了避免子进程成为僵尸进程,父进程需要承担“善后”的责任。具体的处理方式有两种,即调用 wait() 函数和 waitpid() 函数。这两个函数可以让父进程获取子进程的退出状态等信息,并释放子进程所占用的系统资源。

不足之处:

  • 谈到使用多个进程来服务多个客户端的模式。在客户端数量较少,比如只有 100 个的时候,这种方式可能还能满足需求。但是当客户端数量大幅增加到一万个时,这种方式就会面临严重的问题。因为创建每个进程都会消耗系统的资源,比如内存、CPU 时间等。
  • 进程间上下文切换也是一个关键问题。当从一个进程切换到另一个进程时,不仅需要切换用户空间的资源,例如虚拟内存的映射、栈中的数据、全局变量的值等;还需要切换内核空间的资源,像内核堆栈的内容以及各种寄存器的值。这种大量且频繁的上下文切换会带来巨大的开销,导致系统性能显著下降。
  • 例如,假设有一个服务器同时处理多个文件下载的进程。当进程数量较少时,系统能够轻松应对。但如果同时有大量的下载请求,每个请求都创建一个进程,系统可能会因为资源消耗过度和频繁的上下文切换而变得缓慢甚至崩溃。
  • 再比如,在一个多进程的数据库服务器中,如果进程数量过多且上下文切换频繁,可能会导致查询响应时间延长,影响用户体验。

总之,多进程模型在处理少量客户端时可能可行,但在面对大规模客户端时存在诸多限制和问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1842358.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【docker安装rabbitmq】

docker安装rabbitmq 1.查阅rabbitmq的Dokcer Hub官方说明 rabbitmq地址&#xff0c;因为我们需要使用的是带管理界面的rabbitmq服务。所以我们需要下载的rabbitmq:management镜像 docker pull rabbitmq:management2.启动rabbitmq 2.1.快速启动 One of the important thing…

Linux:配置本地yum源仓库

目录 一、挂载光盘到目录下 二、配置本地yum源仓库 一、挂载光盘到目录下 mount /dev/cdrom /mnt/ #把光盘挂载到/mnt目录下 挂载 设备 目录或文件夹 注&#xff1a;最好是空的 原来的数据将被隐藏一个挂载点同一时只能挂载一个设备。 mount /dev…

opencv中凸包运算函数convexHull()的使用

操作系统&#xff1a;ubuntu22.04OpenCV版本&#xff1a;OpenCV4.9IDE:Visual Studio Code编程语言&#xff1a;C11 1.功能描述 该函数cv::convexHull用于寻找一组二维点集的凸包&#xff0c;采用的是Sklansky算法[242]&#xff0c;当前实现中具有O(N logN)的时间复杂度。 1…

【ai】tx2-nx 查看 jetpack 版本信息及对应的tritonserver

3 jtop nvidia@tx2-nx:~$ jtop [WARN] Board missing UNKNOWN (press CTRL + Click) nvidia@tx2-nx:~$ 点击info 可以看到 jetpack是4.6opencv 是4.1.15.1.2 的不适合我 tritonserver2.35.0-jetpack5.1.2-update-2.tgz tritonserver2.19.0-jetpack4.6.1.tgz. 4.6.1<

滚动轴承振动信号异常检测方法总结(NASA-IMS轴承数据,Python)

之前的文章&#xff1a; 基于自编码器的滚动轴承异常检测方法&#xff08;NASA-IMS轴承数据&#xff0c;Python&#xff09; 基于单类支持向量机的滚动轴承异常检测方法&#xff08;NASA-IMS轴承数据&#xff0c;Python&#xff09; 基于主成分分析的滚动轴承异常检测方法&a…

Python运算符重载,代码秒变高大上!

目录 1、运算符重载基础介绍 🧮 1.1 什么是运算符重载 1.2 为何使用运算符重载 1.3 Python中的特殊方法魔法 示例:重载加法运算符 2、实战:重载加法运算符 + 🧩 2.1 自定义类与__add__() 2.2 应用案例:复数加法 2.3 深入理解__add__方法 3、重载其他运算符示例…

js实现canvas截图功能

关键代码 使用canvas的导出功能和drawImage函数 class CropShape{cropShape(shape){let {x,y,w,h} shapeconsole.log(x,y,w,h)const roiCanvas document.createElement(canvas);document.getElementById(app).append(roiCanvas)const roiCtx roiCanvas.getContext(2d);roi…

如何选择理想CDN服务商来提升网站性能

在数字时代&#xff0c;网络速度已成为衡量网站成功的关键指标之一。快速加载的网站不仅提升用户体验&#xff0c;还对网站的搜索引擎排名产生显著影响。用户期望网站能够迅速响应其请求&#xff0c;而任何延迟都可能导致用户不满和流失。研究表明&#xff0c;网站加载时间的每…

【产品经理】订单处理6-审单方案

电商系统中订单管理员会对特殊类型的订单进行审核&#xff0c;普通订单则自动审核&#xff0c;本节讲述自动审单方案、手动审单以及加急审单。 一、自动审单 自动审单方案可按照方案形式制定&#xff0c;可一次性制定多套审单方案。 1. 审单通过条件有 执行店铺&#xff…

Python爬虫实战:淘宝商品爬取与数据分析

一、爬虫技术概述 爬虫技术是一种在互联网上自动收集信息的方法。通过编写程序&#xff0c;让计算机自动访问网站&#xff0c;获取所需数据&#xff0c;并进行分析和处理。Python作为一种功能强大、易于学习的编程语言&#xff0c;其爬虫库Scrapy更是爬虫技术的利器。 二、淘…

段码屏省电低功耗驱动芯片PC164S32|128点阵|低功耗LCD屏专用芯片

1 简介 PC164S32 是一款支持 128 点 (32 4)显示 的多功能 LCD 控制器芯片&#xff0c;内部存储器RAM数据直接映射到 LCD 显示。可软件配置特性使其适用于包括 LCD 模块和显示子系统在内的多种 LCD 应用。主控制器与 PC164S32接口仅需3 或 4 条线。内置的省电模式极大的降低了功…

LangChain入门到精通,看这这篇吊打面试官

导语 在人工智能领域的不断发展中&#xff0c;语言模型扮演着重要的角色。特别是大型语言模型&#xff08;LLM&#xff09;&#xff0c;如ChatGPT&#xff0c;已经成为科技领域的热门话题&#xff0c;并受到广泛认可。在这个背景下&#xff0c;LangChain作为一个以LLM模型为核…

深度学习1 -- 开头

一 前言 感觉用这玩意越来越多&#xff0c;所以想学学。不过没想好怎么学&#xff0c;也没有提纲&#xff0c;买了两本书&#xff0c;一本是深度学习入门&#xff0c;小日子写的。还有一本就是花书。还有就是回Gatech参加线上课程&#xff0c;CS7643。 CS 7643: Deep Learnin…

ps 科研图文字变清晰

目录 网站 PS 网站 AI照片修复神器&#xff0c;一键模糊图片变清晰 (picwish.cn) PS 用PS快速将一张模糊不清晰的照片变清晰&#xff0c;简单5步就好 - 知乎 (zhihu.com) CrtlJ 滤镜 其他 高反差 半径调2 叠加

【机器学习300问】128、简述什么Word2Vec?

一、一句话说明Word2Vec是什么&#xff1f; Word2Vec是一种常见的词嵌入技术。Word2Vec的目标是将每个词表示为一个向量&#xff0c;使得这些向量能够反映出词语之间的相似性和关联性。 word2vec算法通过预测中心词和上下文词的共现概率来学习词向量&#xff0c;能够捕捉词语之…

LeetCode 338.比特位计数

各位朋友们&#xff0c;大家好啊&#xff0c;今天此题我用的方法比较好理解&#xff0c;但时间复杂度比较高如果大家觉得可以的话&#xff0c;不妨给个免费的赞吧&#xff0c;谢谢了^ _ ^ 1.题目要求如图所示: 2.做题步骤: 1.先计算总共多少个数: int count 0;int number 0;…

二叉树(数据结构篇)

数据结构之二叉树 二叉树 概念&#xff1a; 二叉树(binary tree)是一颗每个节点都不能多于两个子节点的树&#xff0c;左边的子树称为左子树&#xff0c;右边的子树称为右子树 性质&#xff1a; 二叉树实际上是图&#xff0c;二叉树相对于树更常用。 平衡二叉树的深度要比…

重磅!鹅厂大牛带你30分钟玩转AI智能结对编程!

在大模型时代&#xff0c;人工智能技术的突破性进展正重塑着软件开发的面貌。AI的融入不仅优化了代码编写过程&#xff0c;更开启了智能编程的新纪元&#xff0c;为开发者带来了前所未有的工作效率和创新可能。AI结对编程不仅能够极大提升研发效率&#xff0c;还能通过智能分析…

C++语法06 格式化输出及保留小数点后指定位数

格式化输出 格式化输出所用的函数为 printf&#xff0c;它可以输出任意位数的小数。 使用格式&#xff1a;printf(“%.nf”,a)。这句话的作用是将变量a保留n位小数输出。 注意事项&#xff1a; 1、这里的n&#xff0c;需要具体化为一个数字&#xff0c;保留几位小数&#x…

MathType软件7.7最新永久激活码许可证秘钥2024最新

【种草神器&#xff01;】大家好啊&#xff0c;我刚刚发现了一个超级好用的工具&#xff0c;迫不及待地想跟大家分享——MathType软件的最新功能介绍。作为一个经常需要处理各种复杂数学公式和文档的科研狗&#x1f436;&#xff0c;找到一款好的数学编辑工具对我来说真的太重要…