百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

linux服务器网络编程之线程模型(linux中线程是怎样创建和运行的)

ahcoder 2025-01-23 14:57 15 浏览

前言

本文将主要介绍传统的和目前流行的进程/线程模型,在讲进程/线程模型之前需要先介绍一种设计模式: Reactor 模式。Reactor 模式首先是事件驱动的,有一个或多个并发输入源,有一个Service Handler,有多个Request Handlers;这个Service Handler会同步的将输入的请求(Event)多路复用的分发给相应的Request Handler。如果用图表示的如下:

关于 Reactor 模式不了解的朋友大家可以看看这几个视频的详细讲解:

手操Reactor设计和线程池实现高并发服务:「链接」

服务器模型,reactor的5种实现方式:「链接」

reactor模型应用:「链接」

不知道读者有没有发现 Reactor 模式跟 IO 模型中的 IO 多路复用模型非常相似 ,在学习网络编程过程中也被这两个概念迷惑了很久。其实在设计模式层面 IO 多路复用也是采用 Reactor 模式的。IO 多路复用模型可以看成是 Reactor 模式在 IO 模型上的应用,而今天我们要讲的是 Reactor 模式在进程/线程模型上的应用。

在我的看来,进程/线程模型可以分为非 Reactor 模式和 Reactor 模式两种(当然还有 Proactor 模式,这种本文先不讲,因为使用的比较少,而且我也还没搞懂这种模式)。非 Reactor 模式和 Reactor 模式的两种进程/线程模型下具体又分很多种,后面会一一列举。非 Reactor 模式的进程/线程模型是传统的模型,现在已经很少见,放在这里主要是让读者做个了解同时与 Reactor 模式的进程/线程模式做个对比。

非 Reactor 模式的进程/线程模型

传统模型不使用 IO 多路使用,所以问题比较多。初学者建议看下这部分,如果你觉得被迷糊了或者不感兴趣可以跳过该部分,直接看 Reactor 模式的部分即可。但该部分的第 1、2 点需要了解下。

1、单进程单线程

描述:这种模型所有的逻辑都在在一个进程中,包括建立连接->Read 连接上的数据->业务处理->Write 回一些数据然后一直循环下去。该模型一次只能处理一个连接,这个在真正的应用中是没有的。初学者在模仿《Unix网络编程卷 I》例子编写网络程序时应该会使用这种模型,当然例子中一般会在 Write 后面多个 Close 连接的动作,以免在处理下一个连接的时候造成前一个句柄泄露。

优点:代码简单,无需去了解进程、线程的概念,适合学习网络编程的初学者。在不了解进程/线程模型情况下的默认模型。

缺点:没有任何实用价值。

2、单进程多线程

描述:进程只做建立连接的动作,每接收一个连接就创建一个线程,在此连接上的读->业务处理->写->关闭连接都在线程中去做,可以采用线程池的方式减少线程的创建和销毁。这种线程模型有一定的应用场景,Tomcat 三种线程模型之 BIO 用的就是这种进程/线程模型。初学者在学习完单进程单线程模型后对线程有所了解即可开始学习该种模型,可以实现一个简单的聊天室程序。

优点:可以同时与多个 Client 建立连接,接收连接和处理连接业务分开。

缺点:每个连接占用一个线程,当连接上没有数据的时候造成线程资源浪费,可以建立的连接数比较有限。

3、多进程单线程

描述:

(1) 主进程启动时创建监听套接字并监听,然后 fork 出 N 个子进程。

(2) 由于父子进程的继承性,子进程同时也在端口监听,然后在父进程中关闭监听。

(3) 父进程负责子进程的创建、销毁、资源回收等,子进程负责连接的建立->Read->业务处理->Write 等。

由于所有进程都在同一个端口监听,该模型会出现一个比较知名的现象---惊群现象:当有一个连接来临时,所有子进程都会被唤醒,但是最后能与 Client 建立连接的只有一个,造成资源浪费(系通调度也是消耗 CPU 的)。不过 linux 2.6 版本以后已经在内核消除了惊群,当有连接来临只会唤醒一个等待在 accept() 上的进程。即使内核没修复,在应用层也可以用锁的方式防止惊群。

缺点:这种模型是单进程单线程的进化版本,然而并没有什么卵用。且增加了开发的难度。所以不列出它的优点,介绍这种模型主要是引出惊群的概念,在后面的 Reactor 模型中的多进程情况下也会出现类似的情况。

C/C++Linux后台服务器开发高级架构师学习视频 点击 正在跳转 获取,内容知识点包括Linux,Nginx,ZeroMQ,MySQL,Redis,线程池,MongoDB,ZK,Linux内核,CDN,P2P,epoll,Docker,TCP/IP,协程,DPDK等等。免费视频学习地址:C/C++Linux服务器开发/后台架构师【零声教育】-学习视频教程-腾讯课堂

Reactor 模式的进程/线程模型

该模式一般是 Reactor 模型 + IO 多路复用,下面的任何一种模型都具有一定的实用场景。

1、单进程单线程

描述:只有一个进程,监听套接字和连接套接字上的事件都由 Select 来处理,

(1) 如果有建立连接的请求过来,Acceptor 负责接受并与之建立连接,同时将连接套接字加入 Select 进行监听;

(2) 如果某个连接上有读事件则进行 Read->业务处理->Write 等操作;

(3) 如此循环反复。

优点:编程简单,对于业务处理不复杂的后台,基本能满足服务器端网络编程。老东家的服务器端程序全是这种模式,主要原因有如下

(1) 如果一台机器性能不行,那就向集群中新增一台。

(2) 业务处理并不复杂。

(3) 扩展成多进程的话,如果不是多核意义不大。

(4) 如果采用单进程多线程,C++ 处理线程不像 Java 简单,还要考虑并发的问题,收益比不大。

缺点:会有阻塞,在进行业务处理的时候不能进行其他操作:如建立连接,读取其他套接字上的数据等。

2、单进程多线程

描述:与单进程单线程类似,不同的是该模型将业务处理放在线程中,进程就不会阻塞在业务处理上。

优点:比较完美的进程/线程模型,在 Java 实现中复杂度也不高。很多网络库都是基于此,比如 Netty 。

缺点:待补充。

3、多进程单线程:

描述:与非 Reactor 模式中的多进程单线程相似,只是本模式在子进程中使用了 IO 多路复用,实用性以下就上来了。大名鼎鼎的 nginx 就采用这种进程/线程模型

优点:编程相对简单,充分利用多核。能满足高并发,不然 nginx 也不可能采用这种模式。

缺点:子进程还是会阻塞在业务处理上。

4、多进程多线程

描述:这里不再画出图形,就是在在子进程上将业务处理交给多线程处理,参考单进程多线程里的线程池那里。

优点:充分利用多核同时子进程不会阻塞在业务处理上

缺点:编程复杂。

5、主从进程 +多线程:

描述:前面几种 Reactor 模式的进程/线程模型中,连接的建立和连接的读写都是在同一进程中。本模型中将连接的建立和连接读写放在不同的进程中。

(1) 主进程在监听套接字上 Select 阻塞,一旦有请求过来则与之建立连接,并将连接套接字传递给从进程。

(2) 从进程在连接套接字上 Select 阻塞,一旦连接上有数据过来则进行 Read,并将业务处理通过线程来处理。如果有必要还会向连接 Write 数据。

优点:连接的建立和连接的读写分开在不同进程中,处理效率会更高。该模型比单进程多线程模式还更优一点,且也可以利用多核。

缺点:编程复杂。

总结

以上就是常见的进程/线程模型,使用了 IO 多路复用的线程模型一般都可以称为 Reactor 模型,所以不用纠结 IO 多路复用与 Reactor 模式之间的关系。



相关推荐

Linux基础运维篇:Linux日志管理(第013课)

日志是什么Linux系统中的日志就像是一个记录员,它会把系统中发生的各种事情都记录下来,比如系统什么时候启动了、哪些用户登录了系统、运行了哪些程序、程序有没有出错、硬件有没有问题等等。这些记录对于系...

目标取代deb包格式,深度Linux操作系统公布“如意玲珑”项目

IT之家7月16日消息,7月13日,在上海站的deepinMeetup如意玲珑专场上,深度操作系统官方正式宣布了项目全新的品牌名称——如意玲珑(Linyaps)。目前如意玲珑已...

基于 Linux 快速搭建私有化 Helm Chart 仓库(ChartMuseum 实战指南)

一、前言在Kubernetes中,Helm是最流行的包管理工具,用于简化应用部署与管理。如果你希望在内网环境中部署、管理自己的HelmCharts,就需要搭建一个私有化HelmChart...

Linux环境开发效率--那些强大的命令

之前写了一篇关于linux下常用的几个命令,参考Linux入门--提高工作效率的命令。接下来接着介绍一些在linux下做开发经常使用到得命令,其中有打包压缩命令tar,文件查找命令find,文件内容查...

怎么使用再生龙打包(备份)liunx系统

liunx系统区别于Windows,由于分区格式的特殊性并不能像GHOST那样进行备份封包,有款开源的针对liunx系统备份还原的软件-再生龙(clonezilla),可能有部分人已经用过,本篇文章让...

python打包那些事儿(python的打包)

python是个万金油,什么活都能干,开发一些小应用的时候,要想其他人也方便使用,就需要对程序进行打包生成可执行文件,不再依赖python环境或者其他文件。前几天写了一个视频去水印的小程序,主要依赖f...

「项目部署」使用Jenkins一键打包部署SpringBoot应用

前言嗨,大家好,我是希留,一个被迫致力于全栈开发的老菜鸟。一般而言,一个项目部署的由:拉取代码->构建->测试->打包->部署等过程组成,如果我们经常需要部署项目,特别是在微服...

Linux面试最高频的5个基本问题(linux面试题必会题目)

CPU利用率和CPU负载的区别是什么提到CPU利用率,就必须理解时间片。什么是CPU时间片?我们现在所使用的Windows、Linux、MacOS都是“多任务操作系统”,就是说他们可以“同时”运行多...

jtti:如何将Linux服务器的文件系统创建成镜像

如何将Linux服务器的文件系统创建成镜像?如何把Linux文件系统创建成一个镜像文件,也就是"系统打包"?这类操作不仅适用于迁移、备份,还能用于批量部署、自定义系统安装,甚至可以作为...

用Nuitka打包 Python,效果竟如此惊人!

使用Python开发一个程序后,将Python脚本打包成独立可执行文件是一项常见需求。Nuitka是一个Python到C的编译器,它会将Python代码转换为等效的C代码,然后使用标...

Linux基础运维篇:Linux软件包管理(第014课)

什么是软件包管理在Linux系统中,软件包管理就像是一个“软件管家”,负责软件的安装、卸载、更新以及软件之间依赖关系的处理。它把软件及其相关的文件、配置信息等打包在一起,方便用户进行管理和操作。...

给你的Nodejs后端项目打个包(node为基础的后端框架)

前阵子,碰到个问题用Nodejs做了个小项目需要交付客户使用之前Nodejs做的都是自用,所以也没碰到需要打包保护源码之类的问题上网搜了半天,找到的大多是针对Vue的前端项目打包/混淆,例如用...

爆强!直接把 Python 编写的图形程序打包为安卓 APP

请大家多多关注点赞哦如果想使用Python语言编写图形界面程序,那么有不少的框架可以提供支持,比如Tkinter、QtforPython、WxPython等等。不过这些框架都是只能创建桌面图...

几行代码教你zip打包(打包zip命令)

01准备有时我们不想去手动一个个去操作,然后傻等他打包完,python依赖库zipfile很方便地帮助我们封装了解压压缩,shutil用于文件目录处理,方法类似于linux命令。1、安装pipin...

Linux基础运维篇:Linux文件操作超详细版(第007课)

一、Linux文件系统基础1.文件类型Linux一切皆文件,常见文件类型:普通文件(-):文本文件(.txt)、二进制文件(可执行程序)、压缩文件等。目录文件(d):用于组织文件和子目录(类似...