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

前言

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

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

进程、线程、协程

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

概念

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

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

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

线程与进程

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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode每日一题】2645. 构造有效字符串的最少插入数(计算组数+动态规划+考虑相邻字母)

2024-1-11 文章目录 [2645. 构造有效字符串的最少插入数](https://leetcode.cn/problems/minimum-additions-to-make-valid-string/)方法一&#xff1a;计算组数方法二&#xff1a;动态规划方法三: 考虑相邻字母 2645. 构造有效字符串的最少插入数 方法一&#xff1a;计算组数 …

【IC设计】ICer‘s 乾坤大挪移——FSM状态机

目录 理论解读写几段式状态机&#xff1f; 设计实战两种state的FSM&#xff08;异步复位&#xff09; 理论解读 写几段式状态机&#xff1f; 设计实战 两种state的FSM&#xff08;异步复位&#xff09; 实现下图所示的摩尔状态机&#xff0c;复位为异步复位。 代码实现&am…

多无人机编队飞行

matlab2020可运行 GitHub - Zhao-Jichao/Distributed_optimal_-formation_control_of_heterogeneous_multi-agent_systems_with_mixed-orders: 异构混合阶多智能体系统编队控制的分布式优化

【添加墨水注意事项]

添加墨水注意事项 当液位灯亮起时请添加墨水&#xff0c;添加墨水应时戴好护目镜和手套.注意墨水不要洒在设备注意墨水要避光保护防止固化 请使用本公司配套专用墨水&#xff0c;添加时注意墨水颜色 禁止儿童接触墨水及容器&#xff0c;如不慎接触眼睛或者误服应立即以大量清…

安全漏洞周报(2024.01.01-2023.01.08)

漏洞速览 ■ 用友CRM系统存在逻辑漏洞 漏洞详情 1. 用友CRM系统存在逻辑漏洞 漏洞介绍&#xff1a; 某友CRM系统是一款综合性的客户关系管理软件&#xff0c;旨在帮助企业建立和维护与客户之间的良好关系。它提供了全面的功能&#xff0c;包括销售管理、市场营销、客户服…

K8S 存储卷

意义&#xff1a;存储卷----数据卷 容器内的目录和宿主机的目录进行挂载 容器在系统上的生命周期是短暂的&#xff0c;delete,k8s用控制器创建的pod&#xff0c;delete相当于重启&#xff0c;容器的状态也会回复到初始状态 一旦回到初始状态&#xff0c;所有的后天编辑的文件…

机器人制作开源方案 | 乒乓球自动拾取机器人

作者&#xff1a;刘众森、王森、王绘东、崔岳震、宋维鑫 单位&#xff1a;山东农业工程学院 指导老师&#xff1a;潘莹月、廖希杰 1. 场景调研 我们小组选择项目的任务方向乒乓球的捡取与存放&#xff0c;针对此问题我们研发了一款乒乓球自动拾取机器人。众所周知&#xff0…

序列模型(4)—— Scaling Laws

本文介绍 LLM 训练过程中重要的 Scaling Laws&#xff0c;这是一个经验规律&#xff0c;指出了固定训练成本&#xff08;总计算量FLOPs&#xff09; C C C 时&#xff0c;如何调配模型规模&#xff08;参数量&#xff09; N N N 和训练 Token 数据量 D D D&#xff0c;才能实现…

提升测试多样性,揭秘Pytest插件pytest-randomly

大家可能知道在Pytest测试生态中&#xff0c;插件扮演着不可或缺的角色&#xff0c;为开发者提供了丰富的功能和工具。其中&#xff0c;pytest-randomly 插件以其能够引入随机性的特性而备受欢迎。本文将深入探讨 pytest-randomly 插件的应用&#xff0c;以及如何通过引入随机性…

Untiy HTC Vive VRTK 开发记录

目录 一.概述 二.功能实现 1.模型抓取 1&#xff09;基础抓取脚本 2&#xff09;抓取物体在手柄上的角度 2.模型放置区域高亮并吸附 1&#xff09;VRTK_SnapDropZone 2&#xff09;VRTK_PolicyList 3&#xff09;VRTK_SnapDropZone_UnityEvents 3.交互滑动条 4.交互旋…

云端建模:开启三维重建的全新时代

在数字化时代的浪潮下&#xff0c;建筑设计和地理信息科学领域正迎来一场前所未有的变革。云端建模作为一项创新技术&#xff0c;以其强大的能力和创造性的方法&#xff0c;正开启着实景三维建模与倾斜摄影三维重建的全新时代。这一时代不仅为测绘工程师、设计师和决策者带来了…

Windows系统下python版本Open3D-0.18.0 的快速安装与使用

目录 一、安装Anaconda3二、安装open3d三、测试代码四、结果展示五、测试数据 Windows系统下python版本Open3D-0.18.0 的快速安装与使用由CSDN点云侠原创&#xff0c;爬虫自重。如果你不是在点云侠的博客中看到该文章&#xff0c;那么此处便是不要脸的爬虫。 一、安装Anaconda…