进程、线程、协程的对比、区别和联系,进程之间的通信方式、线程之间的通信方式、协程之间的通信方式

前言

之前的一篇文章曾写过一些关于进程、线程、协程的内容——进程、线程、协程… … ——任务管理器的性能里都有什么?那么多的线程,进程、线程、句柄都是什么?

但对其之间的通信方式还是没有太过详细了解,因此特写此,归纳旧知识、学习新知识。

进程、线程、协程

此部分是八股文的复习,在我的上篇文章中总结过一些就直接复制来了,不完善地方还请大佬们补充。

概念

进程:进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。

线程:线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。一个进程可以有一个或多个线程,各个线程之间共享程序的内存空间。

协程:是一种基于线程之上,但又比线程更加轻量级的存在,这种由程序员自己写程序来管理的轻量级线程叫做『用户空间线程』,具有对内核来说不可见的特性。

线程与进程

1、线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位;
2、一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线;
3、进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级的资源(如打开文件和信号),某进程内的线程在其它进程不可见;
4、调度和切换:线程上下文切换比进程上下文切换要快得多。

线程与协程

按我个人理解其实就是一句话:协程是用户态的,更迷你版本的线程。执行过程中分配给线程去执行 (具体过程就是gmp模型的内容了)

此处引用一张图 对其进行对比。

在这里插入图片描述

进程之间的通信方式

此部分学习参考自小林Coding 5.2 进程间有哪些通信方式?
引用的图也都来自于小林Coding 5.2 进程间有哪些通信方式?

每个进程的用户地址空间都是独立的,一般而言是不能互相访问的,但内核空间是每个进程都共享的,所以进程之间要通信必须通过内核。
在这里插入图片描述

1、管道。

概述

小林举例的指令没看过,所以找一个自己熟悉一些的——查看端口占用。

netstat -aon|findstr "8081"

在这其中,|就是管道。他的功能是将前一个指令的输出,作为后一个指令的输入——因此来说,管道是单向的。

基于Linux一切皆文件的思想,管道也是文件,实际上就是内核中的一串缓存。通过管道的一端写入数据,另一段读取数据,从而实现通信。父进程关闭f[0],只负责写;子进程关闭f[1],只负责读。双向通信需要两个管道!
在这里插入图片描述
对于匿名管道,只能是父子进程,之间通过fork来进行通信。
对于命名管道,就是创建了一个文件,所以实现不同进程的通信。

缺点

管道这种通信方式效率低,不适合进程间频繁地交换数据

消息队列

主要是解决了管道效率低的问题。

概述

消息队列的工作模式是“A把数据放到对应的消息队列,B需要用时候再去读取”。

其次,消息队列是保存在内核中的消息链表。发送的消息是用户自定义的数据类型,发送接受方要约定好,读完即删。

消息队列和管道的对比

1、消息队列发的是消息体(数据块),管道发的是字节流。
2、消息队列的生命周期随内核,直到释放或者操作系统关闭。管道的周期是随进程的创建而建立,随进程的结束而销毁。

缺点

1、消息队列不适合比较大数据的传输。
2、消息队列通信过程中,存在用户态与内核态之间的数据拷贝开销。

共享内存

主要是解决了 消息队列的读取和写入的过程,都会有发生用户态与内核态之间的消息拷贝过程 的问题。

概述

操作系统内存采取的是虚拟内存机制,每个进程都有自己独立的虚拟内存空间,不同进程的虚拟内存映射到不同的物理内存中。因此共享内存的机制,就是拿出一块虚拟地址空间来,映射到相同的物理内存中。
在这里插入图片描述

信号量

共享内存通信带来了新的问题——是如果多个进程同时修改同一个共享内存,很有可能就冲突了。因此使用信号量机制,保护共享的资源。

概述

信号量其实是一个整型的计数器,主要用于实现进程间的互斥与同步,而不是用于缓存进程间通信的数据。
一共有两个操作:P和V。
P代表-1,V代表+1,如果加减后的信号量。>0代表有空闲,<0代表没有空闲。==0时候,根据是加还是减进行判断。(此段原文拗口,不知道这样总结对不对)
信号量初始化为1时,则代表为互斥信号量。
信号量初始化为0时,则代表为同步信号量。(比如生产者消费者,先消费的话就会被阻塞,直到生产了才唤醒。)

信号

信号和信号量不是一回事!就好比Java和JavaScript的区别。
具体指的就是这些,比如常用的Ctrl+c终止进程,就是一个信号。
在这里插入图片描述

Socket

就是通常所知的那个socket网络通信。

实现 TCP 字节流通信: socket 类型是 AF_INET 和 SOCK_STREAM;
实现 UDP 数据报通信:socket 类型是 AF_INET 和 SOCK_DGRAM;
实现本地进程间通信: 「本地字节流 socket 」类型是 AF_LOCAL 和 SOCK_STREAM,「本地数据报 socket 」类型是 AF_LOCAL 和 SOCK_DGRAM。另外,AF_UNIX 和 AF_LOCAL 是等价的,所以 AF_UNIX 也属于本地 socket;

在这里插入图片描述

在这里插入图片描述

线程间通信机制

此部分看的很懵逼…貌似都是和语言相关一点?这里仅学习一下相关的,其余埋个坑日后再补了。
参考资料:

https://blog.csdn.net/J080624/article/details/87454764

互斥锁确保同一时间只能有一个线程访问共享资源。当锁被占用时试图对其加锁的线程都进入阻塞状态(释放CPU资源使其由运行状态进入等待状态)。当锁释放时哪个等待线程能获得该锁取决于内核的调度。

读写锁当以写模式加锁而处于写状态时任何试图加锁的线程(不论是读或写)都阻塞,当以读状态模式加锁而处于读状态时“读”线程不阻塞,“写”线程阻塞。读模式共享,写模式互斥。

条件变量可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。

自旋锁上锁受阻时线程不阻塞而是在循环中轮询查看能否获得该锁,没有线程的切换因而没有切换开销,不过对CPU的霸占会导致CPU资源的浪费。 所以自旋锁适用于并行结构(多个处理器)或者适用于锁被持有时间短而不希望在线程切换产生开销的情况。

协程间的通信机制

omg,作为一名gopher,八股的进程线程相关都要再加一个协程哈哈哈,学习量暴涨50%!(开玩笑)

Go语言是为并发而且生的语言,因此并发、协程也都是其中很重要的一个概念。自然要学习一下协程间的通信机制。

通过全局变量

全局变量是最简单理解、易于实现但是功能所限的一个方式。简单假设一个场景,主goroutine需要通知所有goroutine退出。

那么如何通过全局变量实现呢?——设置一个bool的全局变量,每个goroutine在运行时都自动检测bool的值,当他为false时,则结束。

如此看来,全局变量实现起来十分的简单。但其功能也十分受限——1、只能单向从主goroutine通知,不能接受回复,也不能实现子goroutine之间通信。
2、只能是一个写,多个去读。如果多个都想写,可以通过加锁来实现,但就太麻烦了,不值得。

channel通信

channel通信,就是不同协程之间通过channel传递发送信息。具体使用时,是通过WaitGroup实现的。
使用前wg.add(1),使用结束后wg.done(),同时通过Wait等待所有完成。
此外还有select机制,具体参考select机制。

Context

Context是上下文,可以通过上下文传递协程的当前状态等信息。具体参考此文——上下文 Context

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flink构造宽表实时入库案例介绍

1. 安装包准备 Flink 1.15.4 安装包 Flink cdc的mysql连接器 Flink sql的sdb连接器 MySQL驱动 SDB驱动 Flink jdbc的mysql连接器 2. 入库流程图 3. Flink安装部署 上传Flink压缩包到服务器&#xff0c;并解压 tar -zxvf flink-1.14.5-bin-scala_2.11.tgz -C /opt/ 复…

7个JavaScript面试题全面解析,一文搞定技术面试

JavaScript是构建网络的主要基石之一。这个强大的语言也有自己的怪癖。例如,您知道0 -0计算为true,或者Number("")产生0吗? 问题在于,这些怪癖有时会让你抓耳挠腮,甚至质疑Brendon Eich发明JavaScript的那一天是不是high了。当然,这里的重点不是说JavaScript是一种…

金融帝国实验室(Capitalism Lab)V10版本游戏平衡性优化与改进

即将推出的V10版本中的各种游戏平衡性优化与改进&#xff1a; ————————————— 一、当玩家被提议收购一家即将破产的公司时&#xff0c;显示商业秘密。 当一家公司濒临破产&#xff0c;玩家被提议收购该公司时&#xff0c;如果玩家有兴趣评估该公司&#xff0c;则无…

【Axure高保真原型】树控制内联框架

今天和大家分享树控制内联框架的原型模板&#xff0c;点击树的箭头可以打开或者收起子节点&#xff0c;点击最后一级人物节点&#xff0c;可以切换右侧内联框到对应的页面&#xff0c;左侧的树是通过中继器制作的&#xff0c;使用简单&#xff0c;只需要按要求填写中继器表格即…

【二】为Python Tk GUI窗口添加一些组件和绑定一些组件事件

文章目录 背景系统环境添加一些组件添加一个Tab标签Frame标签内添加两个单选框、按钮为按钮添加事件&#xff08;预览图片、生成图片按钮和事件&#xff09; 运行示例添加notebook组件和frame组件&#xff08;见标题【添加一个Tab标签】&#xff09;在frame组件上添加单选框和按…

dpdk20.11.9 编译arm版本以及在arm 应用中引用dpdk20.11.9

以往19版本的dpdk 都是可以直接用make 的方式进行编译, e.g, make Tx86_64-native-linux-gcc install 为了和客户那边用的DPDK 版本一致, 这次要用dpdk20.11.9, 并且要把之前跑在X86 版本的服务器上的程序跑在ARM 版本上. 目前有两个问题: 1. 编译出arm 版本的dpdk. 2. 把…

Spark与云存储的集成:S3、Azure Blob Storage

在现代数据处理中&#xff0c;云存储服务如Amazon S3和Azure Blob Storage已成为存储和管理数据的热门选择。与此同时&#xff0c;Apache Spark作为大数据处理框架也备受欢迎。本文将深入探讨如何在Spark中集成云存储服务&#xff0c;并演示如何与S3和Azure Blob Storage进行互…

R语言安装教程(附安装包链接)

R是用于统计分析、绘图的语言和操作环境。R是属于GNU系统的一个自由、免费、源代码开放的软件&#xff0c;它是一个用于统计计算和统计制图的优秀工具。 Mac支持M1芯片&#xff0c;下载其中的arm即可&#xff0c;其余下载另一个文件 下载链接&#xff1a; 链接: https://pan…

Python如何使用Excel文件

使用Python操作Office——EXCEL 首先介绍下office win32 com接口&#xff0c;这个是MS为自动化提供的操作接口&#xff0c;比如我们打开一个EXCEL文档&#xff0c;就可以在里面编辑VB脚本&#xff0c;实现我们自己的效果。对于这种一本万利的买卖&#xff0c;Python怎么能放过…

怎么样检查自己系统上的Python环境中是否有某个包(扩展库)?

比如我们这里想看下有没有库pytz 很简单&#xff0c;进入Python的命令行&#xff0c;然后输入下面的命令&#xff1a; import pytz如果有这个库&#xff0c;则不会报错&#xff0c;否则会报错。 Windows的测试结果如下&#xff1a; Centos的测试结果如下&#xff1a;

【LV12 DAY12-13 GPIO C 语言与寄存器封装】

GPIO 通用型输入输出&#xff0c;GPIO可以控制连接在其引脚实现信号的输入和输出 芯片的引脚和外部设备相连从而实现与外部硬件的通讯&#xff0c;控制&#xff0c;信号采集的功能。 控制CHG_COK引脚输出为高电平&#xff0c;LED亮&#xff0c;输出为低电平&#xff0c;LED熄灭…

麦芯(MachCore)开发教程1 --- 设备软件中间件

黄国强 2024/1/10 acloud163.com 对任何公司来说&#xff0c;在短时间内开发一款高质量设备专用软件&#xff0c;是一件不太容易做到的事情。麦芯是笔者发明的一款设备软件中间件产品。麦芯致力于给设备厂商提供一个开发工具和平台&#xff0c;让客户快速高效的开发自己的设备专…

Unity Delaunay三角剖分算法 动态生成

Unity Delaunay三角剖分算法 动态生成 Delaunay三角剖分Delaunay三角剖分 定义Delaunay 边Delaunay 空圆特性 Delaunay 三角形Delaunay 最大化最小角特性 Delaunay 三角形特征Delaunay 算法Delaunay Lawson算法Delaunay Bowyer-Watson算法 Unity Delaunay三角剖分 应用Unity 工…

SpringBoot3 WebFlux 可观测最佳实践

前言 链路追踪是可观测性软件系统的一个非常好的工具。它使开发人员能够了解应用程序中和应用程序之间不同交互发生的时间、地点和方式。同时让观测复杂的软件系统变得更加容易。 从Spring Boot 3开始&#xff0c;Spring Boot 中用于链路追踪的旧 Spring Cloud Sleuth 解决方…

08、Kafka ------ 消息存储相关的配置-->消息过期时间设置、查看主题下的消息存活时间等配置

目录 消息存储相关的配置★ 消息的存储介绍★ 消息过期时间及处理方式演示&#xff1a;log.cleanup.policy 属性配置 ★ 修改指定主题的消息保存时间演示&#xff1a;将 test2 主题下的消息的保存时间设为10个小时1、先查看test2主题下的配置2、然后设置消息的保存时间3、然后再…

JavaScript基础课程

JavaScript 基础 - 第1天 了解变量、数据类型、运算符等基础概念&#xff0c;能够实现数据类型的转换&#xff0c;结合四则运算体会如何编程。 体会现实世界中的事物与计算机的关系 理解什么是数据并知道数据的分类 理解变量存储数据的“容器” 掌握常见运算符的使用&#x…

SpringSecurity集成JWT实现后端认证授权保姆级教程-授权配置篇

&#x1f341; 作者&#xff1a;知识浅谈&#xff0c;CSDN签约讲师&#xff0c;CSDN博客专家&#xff0c;华为云云享专家&#xff0c;阿里云专家博主 &#x1f4cc; 擅长领域&#xff1a;全栈工程师、爬虫、ACM算法 &#x1f492; 公众号&#xff1a;知识浅谈 &#x1f525;网站…

【Spring Boot】SpringMVC入门

1.什么是springMVC MVC就是把一个项目分成了三部分&#xff1a; MVC是一种思想。Spring进行了实现,称为Spring MVC。SpringBoot是创建SpringMVC项目的一种方式而已。springMVC对于MVC做出了一些改变&#xff1a; 当前阶段,MVC的概念又发生了一些变化,后端开发人员不涉及前端页…

【JaveWeb教程】(18) MySQL数据库开发之 MySQL数据库设计-DDL 如何查询、创建、使用、删除数据库数据表 详细代码示例讲解

目录 2. 数据库设计-DDL2.1 项目开发流程2.2 数据库操作2.2.1 查询数据库2.2.2 创建数据库2.2.3 使用数据库2.2.4 删除数据库 2.3 图形化工具2.3.1 介绍2.3.2 安装2.3.3 使用2.2.3.1 连接数据库2.2.3.2 操作数据库 2.3 表操作2.3.1 创建2.3.1.1 语法2.3.1.2 约束2.3.1.3 数据类…

从0到1实现html文件转换为markdown文档(进度0.1)

Spider-Man 前言准备环境1、node.js2、git 执行指令顺序报错及其解决方案一、npm 错误&#xff01;可以在以下位置找到此运行的完整日志解决方案 二、没有修改权限解决方案&#xff1a; 注意事项总结 前言 当我们处理文档时&#xff0c;常常会遇到将HTML文档转换为Markdown文档…