当前位置: 首页 > news >正文

白话进程>线程>协程

文章目录

    • 概述
      • 进程
      • 线程
      • 协程
      • 区别与联系
    • 举个栗子
      • 进程例子
      • 线程例子
      • 协程例子
      • 区别与联系的具体体现
    • 代码示例
      • 进程例子
      • 线程例子
      • 协程(Goroutine)例子

概述

进程、线程和协程是计算机科学中的基本概念,它们在操作系统和并发编程中扮演着重要角色。以下是关于它们的详细介绍以及它们之间的区别和联系:

进程

进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配的·基本单位·。每个进程都有自己独立的地址空间,包括文本区域、数据区域和堆栈区域,用于存储程序的代码、变量和运行时产生的数据。进程之间通过队列、文件、套接字等方式进行通信。进程是动态产生的,具有生命周期,从创建到运行再到消亡。操作系统通过进程控制块(PCB)来管理和调度进程。

线程

线程是操作系统进行调度的最小单元,也是程序执行的基本单位。线程是·轻量级·的进程,一个进程中可以包含多个线程,它们共享进程的地址空间和资源,如内存、文件句柄等。每个线程都有自己的独立执行流,包括线程标识符、程序计数器、寄存器集合和堆栈。线程之间可以更方便地共享数据和通信,因为它们属于同一个进程,共享相同的地址空间。多线程编程可以提高程序的响应性、资源共享和更高的系统利用率,但也带来了竞态条件、死锁等同步问题。

协程

协程是一种用户态的轻量级线程,它可以在单线程内实现多个执行线程的切换和调度,而无需依赖操作系统的线程管理机制。协程的创建和切换成本很低,因为它们不需要像·操作系统线程·那样依赖·内核态·的线程切换。协程的调度是由程序员显式控制的,而不是由操作系统调度器来决定。这种协作式调度可以避免操作系统线程的上下文切换开销,并且可以更好地适应特定应用程序的需求。协程可以简化并发编程,因为它们可以在同一线程内执行多个任务,并且可以通过显式的切换来控制任务的执行顺序和并发度。协程适用于需要高并发性能和简洁代码的场景。

区别与联系

  1. 区别

    • 资源分配:进程是资源分配的基本单位,拥有独立的地址空间和系统资源;线程是资源调度的基本单位,共享进程的地址空间和资源;协程则完全由程序控制,不依赖操作系统的资源分配。
    • 独立性:进程是独立的执行实体,拥有独立的PID;线程则依存在应用程序中,由应用程序提供多个线程执行控制;协程则更加轻量级,可以在单线程内实现多个执行线程的切换。
    • 通信方式:进程间通信需要通过队列、文件、套接字等方式;线程间通信可以通过全局变量实现;协程间则通过显式的切换和状态保存来实现通信。
    • 调度方式:进程由操作系统调度器进行调度;线程也由操作系统调度器进行调度,但更加轻量级;协程则由程序员显式控制调度。
  2. 联系

    • 层次关系:进程是线程的容器,一个进程中可以包含多个线程;线程是协程的载体,一个线程中可以包含多个协程。
    • 资源共享:进程和线程都共享系统资源,但线程共享的是进程的地址空间和资源;协程则共享的是线程的执行环境和资源。
    • 并发编程:进程、线程和协程都可以用于实现并发编程,但它们的开销和适用场景不同。进程适用于需要独立执行和资源隔离的场景;线程适用于需要高效并发和资源共享的场景;协程则适用于需要高并发性能和简洁代码的场景。

综上所述,进程、线程和协程在操作系统和并发编程中各有其特点和适用场景。理解它们之间的区别和联系有助于更好地选择和设计并发编程模型。

举个栗子

以下是关于进程、线程和协程的详细例子,以帮助理解它们之间的区别和联系:

进程例子

假设我们有一个图像处理应用程序,该应用程序需要同时处理多个图像文件。为了高效利用系统资源,我们可以为每个图像文件创建一个独立的进程来处理。每个进程都有自己独立的内存空间和系统资源,互不干扰。这样,即使一个进程因为处理复杂图像而耗时较长,也不会影响其他进程的正常运行。

线程例子

现在,考虑一个Web服务器应用程序,它需要同时处理多个客户端的请求。为了提高响应速度和资源利用率,我们可以使用多线程编程。每个客户端请求都由一个独立的线程来处理,这些线程共享Web服务器的地址空间和资源,如内存和文件句柄。这样,服务器可以同时处理多个请求,而无需为每个请求创建独立的进程,从而降低了上下文切换和资源开销。

协程例子

假设我们有一个需要处理大量I/O操作的网络应用程序,如一个聊天室服务器。在这个场景中,我们可以使用协程来优化性能。协程允许我们在单线程内实现多个执行线程的切换和调度,而无需依赖操作系统的线程管理机制。我们可以为每个客户端连接创建一个协程,这些协程在需要等待I/O操作(如网络数据传输)时主动让出控制权,以便其他协程可以运行。这样,即使存在大量的客户端连接和I/O操作,服务器也能保持高效的响应速度和资源利用率。

区别与联系的具体体现

  1. 资源分配与独立性

    • 在进程例子中,每个图像文件处理进程都是独立的执行实体,拥有独立的内存空间和系统资源。
    • 在线程例子中,每个客户端请求处理线程都共享Web服务器的地址空间和资源。
    • 在协程例子中,所有协程都共享同一个线程的执行环境和资源。
  2. 通信与调度

    • 进程间通信需要通过队列、文件、套接字等方式进行。
    • 线程间通信可以通过全局变量或共享内存实现。
    • 协程间则通过显式的切换和状态保存来实现通信和调度。
  3. 并发编程

    • 进程适用于需要独立执行和资源隔离的场景,如图像处理、视频渲染等。
    • 线程适用于需要高效并发和资源共享的场景,如Web服务器、数据库连接池等。
    • 协程则适用于需要高并发性能和简洁代码的场景,如网络应用程序、I/O密集型任务等。

综上所述,进程、线程和协程在并发编程中各有其特点和适用场景。理解它们之间的区别和联系有助于更好地选择和设计并发编程模型,以提高程序的性能、可维护性和可扩展性。

代码示例

以下是使用Go语言分别实现进程、线程和协程(goroutine)的例子。

进程例子

在Go语言中,直接创建和管理进程并不像在C语言中那样直接,但可以通过使用os/exec包来启动外部进程。

package mainimport ("fmt""os/exec"
)func main() {// 启动一个新的进程,运行一个简单的命令,比如 "ls"cmd := exec.Command("ls", "-l")output, err := cmd.CombinedOutput()if err != nil {fmt.Println("Error:", err)} else {fmt.Println("Output:", string(output))}
}

在这个例子中,我们使用exec.Command来创建一个运行ls -l命令的进程,并获取其输出。

线程例子

Go语言并没有传统的线程概念,但它有原生的并发支持,即goroutine。然而,为了展示类似线程的行为,我们可以使用Go语言的sync包中的互斥锁(Mutex)来模拟线程同步。尽管这仍然是基于goroutine的,但我们可以模拟多个“线程”同时访问共享资源。

package mainimport ("fmt""sync""time"
)var (counter intmutex   sync.Mutex
)func increment(wg *sync.WaitGroup) {defer wg.Done()for i := 0; i < 1000; i++ {mutex.Lock()counter++mutex.Unlock()time.Sleep(time.Microsecond) // 模拟一些工作}
}func main() {var wg sync.WaitGroup// 启动多个“线程”(goroutine)for i := 0; i < 5; i++ {wg.Add(1)go increment(&wg)}wg.Wait() // 等待所有goroutine完成fmt.Println("Final Counter:", counter)
}

在这个例子中,我们创建了一个共享变量counter,并用一个互斥锁mutex来保护它。然后,我们启动了多个goroutine,每个goroutine都会增加counter的值。

协程(Goroutine)例子

Go语言的协程(goroutine)是其并发模型的核心。以下是一个简单的例子,展示了如何创建和运行多个goroutine。

package mainimport ("fmt""time"
)func printNumbers(start, end int) {for i := start; i <= end; i++ {fmt.Printf("%d ", i)time.Sleep(100 * time.Millisecond) // 模拟一些工作}
}func main() {// 启动多个goroutinego printNumbers(1, 5)go printNumbers(6, 10)go printNumbers(11, 15)// 为了确保主程序不会立即退出,我们让主goroutine等待一段时间time.Sleep(2 * time.Second)fmt.Println("\nDone")
}

在这个例子中,我们定义了一个printNumbers函数,它打印从startend的数字,并在每次打印后等待100毫秒。然后,我们在main函数中启动了三个goroutine,每个goroutine调用printNumbers函数。为了确保主程序不会立即退出,我们在最后让主goroutine等待2秒。

请注意,由于goroutine是并发执行的,因此输出顺序可能会不同。

相关文章:

白话进程>线程>协程

文章目录 概述进程线程协程区别与联系 举个栗子进程例子线程例子协程例子区别与联系的具体体现 代码示例进程例子线程例子协程&#xff08;Goroutine&#xff09;例子 概述 进程、线程和协程是计算机科学中的基本概念&#xff0c;它们在操作系统和并发编程中扮演着重要角色。以…...

论文阅读:Attention is All you Need

Abstract 贡献&#xff1a; 提出了Transformer&#xff0c;完全基于注意力机制&#xff0c;摒弃了循环和卷积网络。 结果&#xff1a; 本模型在质量上优于现有模型&#xff0c;同时具有更高的并行性&#xff0c;并且显著减少了训练时间。 1. Introduction long short-term …...

【Linux 】文件描述符fd、重定向、缓冲区(超详解)

目录 ​编辑 系统接口进行文件访问 open 接口介绍 文件描述符fd 重定向 缓冲区 1、缓冲区是什么&#xff1f; 2、为什么要有缓冲区&#xff1f; 3、怎么办&#xff1f; 我们先来复习一下&#xff0c;c语言对文件的操作&#xff1a; C默认会打开三个输入输出流&#xf…...

Unity WebGL使用nginx作反向代理处理跨域,一些跨域的错误处理(添加了反向代理的配置依旧不能跨域)

反向代理与跨域描述 什么是跨域&#xff1f; 跨域&#xff08;Cross-Origin Resource Sharing, CORS&#xff09;是指在浏览器中&#xff0c;当一个网页的脚本试图从一个域名&#xff08;协议、域名、端口&#xff09;请求另一个域名的资源时&#xff0c;浏览器会阻止这种请求…...

视频转文字免费的软件有哪些?6款工具一键把视频转成文字!又快又方便!

视频转文字免费的软件有哪些&#xff1f;在视频制作剪辑过程中&#xff0c;我们经常进行视频语音识别成字幕&#xff0c;帮助我们更好地呈现视频内容的观看和宣传&#xff0c;市场上有许多免费的视频转文字软件&#xff0c;可以快速导入视频&#xff0c;进行视频内音频的文字转…...

解决DHCP服务异常导致设备无法获取IP地址的方法

DHCP在网络环境中会自动为网络中的设备分配IP地址和其他关键网络参数&#xff0c;可以简化网络配置过程。但是&#xff0c;如果DHCP服务出现异常时&#xff0c;设备可能无法正常获取IP地址&#xff0c;会影响到网络通信。 本文讲述一些办法可以有效解决DHCP服务异常导致设备无法…...

Python机器学习模型的部署与维护:版本管理、监控与更新策略

&#x1f680; Python机器学习模型的部署与维护&#xff1a;版本管理、监控与更新策略 目录 &#x1f4bc; 模型版本管理 使用DVC进行数据和模型的版本控制&#xff0c;确保可复现性 &#x1f50d; 监控与评估 部署后的模型性能监控&#xff0c;使用Prometheus和Grafana进行实…...

免费送源码:Java+ssm+JSP+Ajax+MySQL SSM汽车租赁管理系统 计算机毕业设计原创定制

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对汽车租赁信息管理等问题&#xff0c;对其进…...

Vivado viterbi decoder license

Viterbi Decoder 打卡以上链接 添加后next后&#xff0c; 会发送lic文件到邮件&#xff0c;vivado导入lic即可...

【FastAdmin】PHP的Trait机制:代码复用的新选择

PHP的Trait机制&#xff1a;代码复用的新选择 大家好&#xff0c;我是田辛老师。最近收到很多同学的私信&#xff0c;询问关于PHP中Trait机制的相关问题。今天&#xff0c;我们就来详细探讨一下这个强大的代码复用工具&#xff0c;以及它在ThinkPHP 5&#xff08;简称Tp5&…...

小红书制作视频如何去原视频音乐,视频如何去原声保留背景音乐?

在视频编辑、音乐制作或个人娱乐中&#xff0c;有时我们希望去掉视频中的原声&#xff08;如对话、解说等&#xff09;&#xff0c;仅保留背景音乐。这种处理能让观众更加聚焦于视频的氛围或节奏&#xff0c;同时也为创作者提供了更多创意空间。选择恰当的背景音乐&#xff0c;…...

netty之Netty使用Protobuf传输数据

前言 在netty数据传输过程中可以有很多选择&#xff0c;比如&#xff1b;字符串、json、xml、java对象&#xff0c;但为了保证传输的数据具备&#xff1b;良好的通用性、方便的操作性和传输的高性能&#xff0c;我们可以选择protobuf作为我们的数据传输格式。目前protobuf可以支…...

【力扣 | SQL题 | 每日四题】力扣2082, 2084, 2072, 2112, 180

四题都比较简单&#xff0c;可以直接秒。 1. 力扣2082&#xff1a;富有客户的数量 1.1 题目: 表&#xff1a; Store ------------------- | Column Name | Type | ------------------- | bill_id | int | | customer_id | int | | amount | int | -------------…...

快速了解Java中的15把锁!

目录 了解 总览 乐观锁 悲观锁 互斥锁和同步锁 公平锁 非公平锁 自旋锁 可重入锁&#xff08;递归锁&#xff09; ReadWriteLock读写锁 共享锁 独占锁 偏向锁 轻量级锁 重量级锁 锁优化 在 Java 中&#xff0c;锁是一种用于实现多线程之间同步和互斥的机制。 了…...

TypeScript 封装 Axios 1.7.7

随着Axios版本的不同&#xff0c;类型也在改变&#xff0c;以后怎么写类型&#xff1f; yarn add axios1. 封装Axios 将Axios封装成一个类&#xff0c;同时重新封装request方法 重新封装request有几个好处&#xff1a; 所有的请求将从我们定义的requet请求中发送&#xff…...

【数据结构】【链表代码】移除链表元素

移除链表元素 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* removeElements(struct ListNode* head, int val) { // 创建一个虚拟头节点&#xff0c;以处理头节点可能被删除的情况 struct…...

作文-杭州游记

杭州的学习与游历 在这个风景如画的城市——杭州&#xff0c;学习信息学的日子如同西湖的水&#xff0c;清澈而又深邃。在这里&#xff0c;课堂与自然的交融、技术与文化的碰撞&#xff0c;构成了一幅独特的画卷。 学习之旅 信息学的课程不仅仅是对代码和算法的解析&#xff0…...

降压芯片TPS54821

降压芯片TPS54821 介绍 价格低廉&#xff0c;只需1.5元。是一个同步整流降压BUCK电路。MOS管内置。输入电压为4.5V至17V&#xff0c;输出电压为0.6V到15V&#xff0c;输出电流最大到8A。是QFN封装&#xff0c;焊接时有些许困难。得益于QFN封装&#xff0c;其引线电感非常的小…...

YOLO v1详解解读

&#x1f680; 在此之前主要介绍了YOLO v5源码的安装和使用&#xff08;YOLO v5安装教程&#xff09;&#xff0c;接下来将探索YOLO的实现原理&#xff0c;作为一个金典的单阶段目标检测算法&#xff0c;应该深度的理解它的构建思想&#xff1b;所以本系列文章将从LOVO v1出发到…...

【动态规划-最长公共子序列(LCS)】【hard】【科大讯飞笔试最后一题】力扣115. 不同的子序列

给你两个字符串 s 和 t &#xff0c;统计并返回在 s 的 子序列 中 t 出现的个数&#xff0c;结果需要对 10^9 7 取模。 示例 1&#xff1a; 输入&#xff1a;s “rabbbit”, t “rabbit” 输出&#xff1a;3 解释&#xff1a; 如下所示, 有 3 种可以从 s 中得到 “rabbit”…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准

城市路内停车管理常因行道树遮挡、高位设备盲区等问题&#xff0c;导致车牌识别率低、逃费率高&#xff0c;传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法&#xff0c;正成为破局关键。该设备安装于车位侧方0.5-0.7米高度&#xff0c;直接规避树枝遮…...