关于高并发场景和进程线程协程的一些总结

news2025/7/19 10:28:25

1、IO复用和线程池哪个好?应用场景?

IO复用就是一个线程处理多个客户端连接。如果自己实现的话,就是要不断轮询每个客户端连接,看看有没有事件发生(数据到达),即使可以用非阻塞的read函数,但是也会花很多时间在CPU空转上,因为可能数据都没到达,就白轮询了。
而系统提供了这种机制,select等模型,让操作系统来实现,只要有一个可读事件就返回(或者超时返回),然后进行处理(至于底层的原理数据结构,看面经积累那篇文章)。至于处理是单线程,还是一个线程处理一个连接(这其实就是reactor模型),具体就看业务场景了。
IO复用适合的场景就是:
1、处理过程简单,因为创建切换线程是需要时间的,如果很简单,一个熟练工自己做就可以,分发给很多人做需要时间,可能分发的时间代价比自己做好这一个连接请求还大。如果处理过程复杂一点,代价比创建切换线程时间大,那么可以多线程。如果完全是一个计算密集的任务,IO消耗可忽略,多进程充分利用CPU核数的计算力更重要,多线程的重要目的就是在IO阻塞时挂起线程让CPU执行别的任务,充分利用CPU,不让他闲置。计算密集型任务基本上就没有IO阻塞这一说,CPU一直是满负载的。并且相对来说,进程更加健壮,进程之间不影响,而线程之间会互相影响,因为是公用内存空间的。
2.适合长连接,有很多闲置IO的场景。因为如果为每个IO设置一个线程,将会大大增加内存消耗,线程创建需要空间(10M左右)。
3.上层应用编程方便。因为多线程会有线程安全,并发编程问题,需要加锁等机制。方便也是一大因素,不然就不会有python这种方便但是性能不够好的语言了。因为可以实现需求比为了性能实现不了需求要好。

比如redis,nigix就是典型的IO复用,单线程的。
nigix反向代理的转发逻辑简单,所以是单线程的。redis因为是基于内存的,CPU不是瓶颈(也就是说逻辑处理很快,相对就是简单),瓶颈可能是网络带宽等,一个CPU完全有足够的算力去实现所有客户端连接的请求处理,单个的请求处理过程很快,不需要让客户端等待很久,反而是创建切换线程会让客户端等的更久。如果并发量特别大,希望充分利用其他的CPU,就可以多开几个redis进程。
redis为什么快
(基于内存,数据用哈希表存储,内存的读写速度非常快,查找和操作的时间复杂度都是O(1))
(redis是单线程的,省去了很多上下文切换线程的时间(避免线程切换和竞态消耗))
(redis使用IO多路复用技术(IO multiplexing, 解决对多个I/O监听时,一个I/O阻塞影响其他I/O的问题),可以处理并发的连接(非阻塞IO))

2、IO复用模型用的是非阻塞IO吗? 阻塞非阻塞,同步异步IO的区别?
首先阻塞IO是什么流程?
在这里插入图片描述
在读的时候,如果没有数据,就一直阻塞等待,这是第一部分,有数据后,将数据从内核复制到用户空间(定义的buffer中),这是第二部分。然后read才完成;
非阻塞IO
在这里插入图片描述
读调用时,如果没有数据,就直接返回错误,不需要阻塞等待,准备好后就拷贝数据到缓冲区。

可以发现,阻塞非阻塞第二步相同,都得等到数据拷贝完成才返回处理数据,因此它们都是同步IO。而异步IO就是第二步拷贝不需要等待完成就直接返回进行下面的代码,拷贝完成后会有信号通知即回调函数完成操作。

那么IO复用是不是阻塞呢?
首先,IO复用在操作系统层面应该是不阻塞的,在应用层面阻塞。首先select函数返回必须有一个可读事件发生,没有的话是会阻塞的,但这是编程层面的,可以通过超时时间来控制。返回后遍历fdset,这时的read调用就是非阻塞的,没有数据直接返回错误,有数据就拷贝到缓冲区,并处理。

4、多线程为什么能提高并发度?和CPU核数的关系?单核跑多线程有意义吗?
多线程,多进程在单核跑有意义吗?我们要了解多线程的应用场景。
多线程主要用于有很多IO操作的地方,比如磁盘IO,网络IO。IO操作时不需要占用cpu时间的,一个cpu同一时刻只能被一个线程占用。当一个线程在IO操作被阻塞时,完全可以让出CPU,让需要CPU的线程执行。所以意义就是错开IO和cpu的使用。一个线程是串行处理所有操作,一个客户端处理完再处理下一个,有IO时CPU就空闲等待。而多线程的话,一个客户端处于IO时,CPU就让另一个需要IO的客户端执行,这样CPU利用率变高了,每个客户端处理的速度也变快了。但是如果计算密集的话,没有IO时间,就不需要多线程。
有多个CPU时,多线程就更加能发挥作用了,充分利用多个CPU的处理能力。现在的处理器一般都是好多CPU核心的。

所以个人经验:如果逻辑处理很简单,就用IO复用+单线程;如果逻辑处理稍微复杂,大于创建切换线程的时间,就用IO复用+多线程(线程池);如果完全是计算密集的任务,就看几个CPU核心,开几个进程,基本不需要调度进程。

5、系统调用(用户内核态切换)、切换线程,协程,进程到底要多少时间?做了什么事情?
首先,系统调用做的是就是进程内将用户态切换到内核态,然后再切回来。大概是ns级别,开销比较小;并且进程线程切换都得经过用户态到内核态的转换。
进程切换大概是3.5us,毫秒级别,开销较大。(实验方法是创建两个进程并在它们之间传送一个令牌。其中一个进程在读取令牌时就会引起阻塞。另一个进程发送令牌后等待其返回时也处于阻塞状态。如此往返传送一定的次数,然后统计他们的平均单次切换时间开销。)
这些开销主要分成两部分:直接开销:PCB的修改,调度器的执行,全局页表目录的修改,硬件上下文(返回地址等)
间接开销:虽然切换到一个新进程后,由于各种缓存并不热,速度运行会慢一些。如果进程始终都在一个CPU上调度还好一些,如果跨CPU的话,之前热起来的TLB、L1、L2、L3因为运行的进程已经变了,所以以局部性原理cache起来的代码、数据也都没有用了,导致新进程穿透到内存的IO会变多。

线程开销较小,因为共享进程的虚拟地址空间,没有页表的切换,TLB命中率降低等因素。只要切换自己的栈和程序计数器PC即可。也是毫秒级别。

为了实现异步,通常会用回调函数,这样可以尽量避免线程切换的开销。但是这么做不是人类正常的思维,代码维护困难。最好可以用同步的代码写出异步的效果,协程可以做到。协程在应用层又动起了主意,设计出了不需要进程/线程上下文切换的“线程”,协程。用协程去处理高并发的应用场景,既能够符合进程涉及的初衷,让开发者们用人类正常的线性的思维去处理自己的业务,也同样能够省去昂贵的进程/线程上下文切换的开销
协程开销大概是120ns,甚至比系统调用还快。并且协程的内存占用只有KB级别,也很小。

协程缺点就是,需要程序员自己执行切换时机,不像进程线程,操作系统会完成这些步骤。操作系统的一个主要设计目标是实时性,对优先级比较高的进程是会抢占当前占用CPU的进程。但是协程无法实现这一点,还得依赖于使用CPU的一方主动释放,与操作系统的实现目的不相吻合。协程的高效是以牺牲了可抢占性为代价的。所以协程的调度设计很重要。
另外,协程的栈空间太小了,一旦比较复杂的业务,很有可能会溢出。

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

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

相关文章

基于java+sql+servlet的金融借贷管理系统mysql数据源

基于javasqlservlet的金融借贷管理系统 一套基于基于JavaWeb实现的金融借贷系统 或 P2P金融管理系统 或 小额贷款系统,详细介绍了金融借贷系统的实现,包括:1.项目介绍2.环境搭建3.系统功能4.技术实现5.项目运行6.功能演示以通俗易懂的方式&a…

浏览器自动化框架沦为攻击者的工具

5月27日消息,安全公司Team Cymru的研究人员表示,越来越多的威胁参与者正在使用免费的浏览器自动化框架作为其攻击活动的一部分。 研究人员表示,该框架的技术准入门槛故意保持在较低水平,以创建一个由内容开发者和贡献者组成的活跃…

算法训练营 day55 动态规划 买卖股票问题系列3

算法训练营 day55 动态规划 买卖股票问题系列3 最佳买卖股票时机含冷冻期 309. 最佳买卖股票时机含冷冻期 - 力扣(LeetCode) 给定一个整数数组prices,其中第 prices[i] 表示第 i 天的股票价格 。 设计一个算法计算出最大利润。在满足以下…

JavaScript高级 Proxy Reflect

1. Proxy 1. 监听对象的变化 有一个对象,我们希望监听这个对象中的属性被设置或获取的过程 我们可以通过 Object.defineProperty 来实现 const obj {name: "why",age: 18,height: 1.88 }// 需求: 监听对象属性的所有操作 // 监听属性的操作 // 1.针对…

MySQL中的一些非常实用的函数、语法

前言我最近几年用MYSQL数据库挺多的,发现了一些非常有用的小玩意,今天拿出来分享到大家,希望对你会有所帮助。1.group_concat在我们平常的工作中,使用group by进行分组的场景,是非常多的。比如想统计出用户表中&#x…

Qt图片定时滚动

目录参考结构PicturePlay.promain.cpppictureplay.hpictureplay.cpppictureplay.ui效果参考 Qt图片浏览器 QT制作一个图片播放器 Qt中自适应的labelpixmap充满窗口后,无法缩小只能放大 可以显示jpg、jpeg、png、bmp。可以从电脑上拖动图到窗口并显示出来或者打开文件…

LDO 芯片烫手,问题出在哪里?

设计失误的一个电路,该电路是数字电路的电源,为图方便对12V直接通过线性电源芯片降压到5V: 图1:线性电源降压12V转5V 几块电路板打样好后,测试均发现AMS1117-5.0芯片烫手,负载电流100mA多,也满…

vim命令快捷键

1.概述vim在linux系统下代码补全、编译及错误跳转等方便编程的功能丰富,被广泛使用。简单的来说, vi 是老式的字处理器,不过功能已经很齐全了,但是还是有可以进步的地方。 vim 则可以说是程序开发者的一项很好用的工具。vim 是一个…

从零开始的机械臂yolov5抓取gazebo仿真(环境搭建篇中)

yolov5运行环境搭建 本篇主要讲如何搭建yolov5运行环境,以及一些需要注意避坑的重要知识点。anaconda与显卡驱动先装后装是没有什么影响的,关键在于,不能将显卡驱动以及cuda装在虚拟环境中。这里介绍一下博主的电脑环境为i7九代ubuntu18.04r…

移动办公时代,数智化平台如何赋能企业管理升级?

在传统的办公模式下,企业组织办公不仅时效低,周期长、成本高,且各办公系统相互独立。随着社会经济的发展,人们的工作生活变得多样化,对于办公的需求也越来越多,存在明显弊端的传统办公模式已不能满足企业对…

基于Mirai框架的Chatgpt_qq机器人搭建

参考项目:https://github.com/lss233/chatgpt-mirai-qq-bot by:雪月三十 采用docker方式搭建 方便快捷 不建议放在云服务器上 本地要有代理才行(也可以自行配置代理) 以下操作均是在有代理的情况下进行的 克隆项目 git clone ht…

狐狸优化算法(Matlab代码实现)

👨‍🎓个人主页:研学社的博客💥💥💞💞欢迎来到本博客❤️❤️💥💥🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密…

K8S篇-搭建kubenetes集群

安装环境 这里使用pve虚拟机搭建三台centos机器,搭建过程参考: Centos篇-Centos Minimal安装 此次安装硬件配置 CPU:2C 内存:2G 存储:64G 环境说明 操作系统:Centos 7.9 内核版本:6.2.0-1.el7.elrepo…

4面美团软件测试工程师,却忽略了这一点,直接让我前功尽弃

说一下我面试别人时候的思路 反过来理解,就是面试时候应该注意哪些东西;用加粗部分标注了 一般面试分为这么几个部分: 一、自我介绍 这部分一般人喜欢讲很多,其实没必要。大约5分钟内说清楚自己的职业经历,自己的核…

论坛项目小程序和h5登录

项目中安装uview出现npm安装uview 直接报错:创建一个package.json配置文件在进行安装。cmd到项目。初始化一个package.json文件(vue项目的配置文件) npm init --yes 安装uview项目点击关注进入管页面,需要验证用户是否登录查用户是…

Python编程自动化办公案例(3)

作者简介:一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页​​​​​​ 目录 前言 一.前几章代码 1.获取到第一题的选项单元格 2.实现批量获取文件 二. 批…

Linux——UDP协议与相关套接字编程

一.概念在网络通信中,传输层中最常用的通信协议有两个:TCP协议与UDP协议。这两种协议虽然都可以用于网络通信,但是通信方式不同决定了应用场景的不同。与TCP协议相比,UDP协议最具特色的不同点有两个:无连接与面向数据报…

kubernetes集群pod中的pause容器作用

kubernetes集群pod中的pause容器作用 我们搭建完集群了以后,可以使用最简单的方式创建一个pod,随意你建立什么pod,去访问相应node上执行docker ps 就会看到有一种pause容器,但是你可能从来没有启用 etrics-scraper_dashboard-me…

C++中的内存管理

文章目录前言1.C中内存空间的划分2.C内存管理方式1.对内置类型的处理2.对自定义类型的处理3.new和delete实现原理4.定位new3.总结1. malloc/free和new/delete的区别2. 内存泄漏前言 C中的内存空间划分和C语言是很像的,基本上区别不大。但是因C中,引入了…

【华为OD机试模拟题】用 C++ 实现 - 找字符(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 货币单位换算(2023.Q1) 【华为OD机试模拟题】用 C++ 实现 - 选座位(2023.Q1) 【华为OD机试模拟题】用 C++ 实现 - 停车场最大距离(2023.Q1) 【华为OD机试模拟题】用 C++ 实现 - 重组字符串(2023.Q1) 【华为OD机试模…