首页 > 系统相关 >TCP并发服务器多线程和多进程方式以及几种IO模型

TCP并发服务器多线程和多进程方式以及几种IO模型

时间:2024-08-27 21:25:05浏览次数:6  
标签:应用程序 并发 线程 TCP IO 进程 服务器 多线程 客户端

1. 阻塞 I/O(Blocking I/O)

在阻塞 I/O 模型中,当应用程序发起 I/O 操作时,整个进程会被阻塞,直到操作完成。在这个过程中,应用程序无法执行其他任务,必须等待 I/O 操作的完成。

特点

  • 简单性:编程简单,逻辑清晰,容易理解和实现。
  • 低效性:在高并发场景下,由于每个 I/O 操作都会阻塞整个进程,资源利用率较低。

2. 非阻塞 I/O(Non-blocking I/O)

非阻塞 I/O 模型允许应用程序在发起 I/O 操作时立即返回,即使数据尚未准备好。应用程序可以在等待 I/O 完成的同时执行其他任务,需通过轮询(多次尝试)来检查 I/O 是否完成。

特点

  • 并发性:在等待 I/O 完成时,应用程序可以继续处理其他任务。
  • 轮询开销:需要频繁检查 I/O 状态,增加了 CPU 的负担。

3. I/O 多路复用(I/O Multiplexing)

I/O 多路复用(如 selectpollepoll)允许应用程序同时监听多个 I/O 事件,并在任何一个 I/O 操作准备好时被通知。应用程序可以集中处理多个 I/O 操作,从而避免轮询带来的开销。

特点

  • 高效性:适用于需要同时处理多个 I/O 连接的场景,尤其是高并发服务器。
  • 复杂性:编程复杂度高,需要仔细管理多个 I/O 描述符和事件。

4. 信号驱动 I/O(Signal-driven I/O)

信号驱动 I/O 模型中,应用程序发起 I/O 操作并继续执行其他任务,当数据准备好时,内核会通过信号通知应用程序。这种方式允许应用程序避免轮询和阻塞,且能够异步处理 I/O 事件。

特点

  • 异步性:内核通过信号通知应用程序,无需轮询。
  • 复杂性:信号处理逻辑复杂,容易出错。

5. 异步 I/O(Asynchronous I/O)

在异步 I/O 模型中,应用程序发起 I/O 操作并立即返回,I/O 操作由内核完成,操作完成后内核通过回调机制通知应用程序。应用程序无需等待 I/O 完成,也无需轮询或处理信号。

特点

  • 最高效:真正的异步模型,应用程序可以充分利用 CPU 时间。
  • 复杂性:编程难度较大,需要处理异步回调和并发问题。

1. 多线程并发服务器

在多线程模型中,服务器为每个客户端连接创建一个独立的线程。每个线程处理客户端的请求,并将处理结果返回给客户端。由于线程是在同一进程内执行的,因此它们共享内存空间和其他资源。

工作流程:
  1. 主线程监听:服务器在指定端口上监听客户端连接请求。
  2. 接受连接:当有新的客户端连接时,服务器接受该连接,并为其创建一个新的线程。
  3. 线程处理:新线程负责处理该客户端的所有请求,直到客户端断开连接。线程可以读取客户端发送的数据、进行处理,并将结果发送回客户端。
  4. 线程终止:在处理完毕后,线程可以选择继续等待新的请求(长连接)或终止(短连接)。
优点:
  • 资源共享:线程间共享同一进程的资源(如内存、文件描述符),使得在不同线程之间共享数据变得容易。
  • 响应速度快:创建线程的开销相对较低,线程切换也比进程切换快,适合需要快速响应的场景。
缺点:
  • 同步问题:由于线程共享同一地址空间,因此在访问共享资源时,容易出现数据竞争问题,需要使用同步机制(如互斥锁)来避免竞争条件,这会增加代码复杂度。
  • 稳定性:一个线程崩溃可能会影响整个进程,因为所有线程共享同一进程空间。
使用场景:
  • 高并发应用:适合需要处理大量并发连接的场景,如聊天室、实时通信系统。
  • 轻量级任务:当每个请求的处理时间较短时,多线程模型能够有效提高处理效率。

2. 多进程并发服务器

在多进程模型中,服务器为每个客户端连接创建一个独立的进程。每个进程在自己的内存空间中运行,处理来自客户端的请求并返回结果。由于进程是独立的,数据不会在进程之间共享。

工作流程:
  1. 主进程监听:服务器在指定端口上监听客户端连接请求。
  2. 接受连接:当有新的客户端连接时,服务器接受该连接,并为其派生一个新的子进程。
  3. 进程处理:子进程独立运行,处理客户端的请求,直到客户端断开连接。子进程在处理过程中可以读取数据、进行处理,并返回结果。
  4. 进程终止:子进程处理完毕后终止,释放相关资源。
优点:
  • 独立性强:每个进程都有独立的内存空间和资源,因此一个进程崩溃不会影响其他进程的运行,服务器整体的稳定性较高。
  • 安全性高:由于进程间的数据不共享,因此天然避免了线程间的竞争条件和同步问题。
缺点:
  • 资源开销大:创建和销毁进程的开销比线程大得多,尤其是在高并发场景下,进程的频繁创建和销毁可能会耗尽系统资源。
  • 进程通信复杂:如果进程之间需要通信,必须使用 IPC 机制(如管道、消息队列、共享内存等),这增加了开发的复杂度。
使用场景:
  • 高安全性应用:适合对安全性要求较高的场景,如需要严格隔离不同客户端的应用。
  • 长时间任务:适合处理时间较长、复杂度较高的任务,因为进程之间相互独立,不会因为某个进程的长时间运行影响到其他任务的处理。

  • 多线程并发服务器:适合轻量级、高并发的应用场景,能够快速响应请求,但需要注意线程同步问题和稳定性。
  • 多进程并发服务器:适合高安全性、高稳定性的场景,尤其是需要隔离不同任务的应用,但进程开销较大,进程间通信较为复杂。

 fcntl()

  • 原型int fcntl(int fd, int cmd, ... /* arg */ );

  • 用法

    1. 首先,使用 fcntl() 函数获取文件描述符的当前标志。
      • 可以通过传递 F_GETFL 作为 cmd 参数来实现。
    2. 然后,将非阻塞标志 O_NONBLOCK 添加到当前标志中。
    3. 最后,再次使用 fcntl() 函数将新的标志设置回文件描述符。
      • 可以通过传递 F_SETFL 作为 cmd 参数来实现

实现信号驱动 I/O 主要依赖以下函数:

1. 设置文件描述符为信号驱动模式

要将文件描述符设置为信号驱动模式,可以使用 fcntl() 函数。

  • fcntl()
    • 原型int fcntl(int fd, int cmd, ... /* arg */ );

    • 用法

      1. 首先,使用 fcntl() 函数获取文件描述符的当前标志。
        • 通过传递 F_GETFL 作为 cmd 参数来获取当前标志。
      2. 然后,将 O_ASYNC 标志添加到文件描述符的当前标志中。
        • 通过传递 F_SETFL 作为 cmd 参数,并将 O_ASYNC 与现有标志结合来实现。
      3. 最后,使用 fcntl() 设置信号接收进程或进程组:
        • 通过传递 F_SETOWN 作为 cmd 参数,并传递要接收信号的进程 ID 或进程组 ID。

      这样,当文件描述符有 I/O 事件发生时,系统将向指定进程发送 SIGIO 信号。

2. 处理信号

在信号驱动 I/O 中,当文件描述符准备好时,会触发 SIGIO 信号。应用程序需要设置信号处理程序来处理该信号。

  • sigaction()
    • 原型int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

    • 用法

      • 使用 sigaction() 函数为 SIGIO 信号设置一个处理函数。
      • 在信号处理函数中,应用程序可以执行相应的 I/O 操作(如读取或写入数据)。

      通过 sigaction() 配置 SIGIO 信号的处理程序后,应用程序在文件描述符准备好进行 I/O 操作时会自动收到通知并调用处理程序。

标签:应用程序,并发,线程,TCP,IO,进程,服务器,多线程,客户端
From: https://blog.csdn.net/a8687216/article/details/141612323

相关文章

  • Kettle: pentaho-server-ce-9.4 连接失败:ConnectionServiceImpl.ERROR_0009
    pentaho-server-ce-9.4 数据库连接MYSQL8.0.37 ,测试连接失败,提示:ConnectionServiceImpl.ERROR_0009-Connectiontodatabase[MYSQL8]failed. 在TOMCAT\LOGS\catalina.2024-08-27.log日志内容如下:  20:58:27,287ERROR[ConnectionServiceImpl]Errorend:21:0......
  • Docker下使用llama.cpp部署带Function calling和Json Mode功能的Mistral 7B模型
    Docker下使用llama.cpp部署带Functioncalling和JsonMode功能的Mistral7B模型说明:首次发表日期:2024-08-27参考:https://www.markhneedham.com/blog/2024/06/23/mistral-7b-function-calling-llama-cpp/https://github.com/abetlen/llama-cpp-python?tab=readme-ov-file#fu......
  • 目录PyCharm Community Edition、python3.11、pythonProject之间的关系
    PyCharmCommunityEdition类型:PyCharmCommunityEdition是由JetBrains公司提供的免费、开源的集成开发环境(IDE)。用途:它专门为Python开发设计,提供了代码编辑、运行、调试、测试等功能。特点:包括智能代码补全、代码分析、图形化界面设计、版本控制集成等高级功能。Pyt......
  • C# reflection pros and cons
    Copyfrom https://www.erikzhou.com/blogs/reflection_in_csharp/ ProsandConsofReflectionReflectionisapowerfultool,butitcomeswithitsownsetofadvantagesanddisadvantages.Let’sexploretheprosandconsofusingreflectioninC#.ProsDy......
  • C# reflection slower 2.19X+ than direct
    usingSystem.Diagnostics;usingSystem.IO;usingSystem.Reflection;usingSystem.Text;namespaceConsoleApp58{internalclassProgram{staticList<Book>booksList{get;set;}staticvoidMain(string[]args){......
  • HBM芯片PI-SI Cosimulation
    现代电子设计在降低功耗、降低电源电压水平和提高速率方面的趋势要求结合SI-PI共同仿真。需要把PDN的每个部分都应仔细建模,并设计为使I/O驱动器看到的输入阻抗最小化。然后应将PDN与信道模型相结合,通过考虑PDN的影响,如电源引起的抖动和电源导轨上引起的纹波,实现输出眼图的准确......
  • Fins TCP协议理解及C Sharp实现思路
     假设本文中使用到设备的ip地址,用于后续内容的理解:客户端(本机电脑windows系统)IP:192.168.1.101服务端(PLComronCJ2M系列)IP和端口号:192.168.1.10:9600 注意:①本文中的FINSTCP报文都是以16进制(Hex)发送出去的,所以对应的转换也都会转成16进制的形式。②16进制He......
  • MP157-阻塞IO与非阻塞IO
    linux阻塞IO与非阻塞IO一,简介当应用程序对设备驱动进行操作的时候,如果不能获取到设备资源,那么阻塞式IO就会将应用程序对应的线程挂起,直到设备资源可以获取为止。对于非阻塞IO,应用程序对应的线程不会挂起,它要么一直轮询等待,直到设备资源可以使用,要么就直接放弃。......
  • ISSCC submission checklist
    manuscript和figure使用官网提供的模板(manuscript使用ArialNarrow字体,12pt,单栏,双倍行距,figure在2024年更新了模板,直接把图片导入模板中即可)manuscript和figure分别提交(以pdf形式)manuscript连带标题空格等不超过10000总字符数(注意是字符数),标题建议12-14个词,但略微超出问题......
  • Android开发 - Application 基础类全局的应用级状态管理解析
    Application是什么Application是一个基础类,用于全局的应用级状态管理。它在应用程序启动时被创建,并在应用程序关闭时销毁。Application对象的生命周期与应用程序的生命周期一致,因此它非常适合用来保存全局的应用状态信息或初始化全局资源Application的主要作用全局状态管......