> # 进程、线程、协程
**进程**:操作系统中资源分配的基本单位,每个进程有独立的内存空间。进程间隔离较好,但切换开销大。
**线程**:进程中的执行单元,同一进程的线程共享内存和资源。线程比进程轻量,切换开销较小,但需要手动管理同步。
**协程**:比线程更轻量级的执行单元,由用户态调度管理。协程的调度由程序自行控制,性能开销更低,适合大量并发场景。
- 进程:有自己的内存空间和系统资源, 上下文进程切换开销大
- 线程:一个进程可以有多个线程,线程共享进程的内存和资源, 上下文切换开销较小
- 协程:一个线程可以有多个协程,协程是一种用户态的轻量级线程,上下文切换开销小,调度由用户控制
---
1. **进程(Process):**
* 想象你有一个电脑上运行的程序,比如一个游戏。这个游戏就是一个进程。它有自己的内存和资源,与其他程序相互独立。
2. **线程(Thread):**
* 现在,想象这个游戏内部有多个任务,比如同时处理音乐、图形和用户输入。每个任务就是一个线程。这些线程共享游戏的内存和资源。
3. **协程(Coroutine):**
* 现在,想象你在游戏中有一些小任务,比如同时进行的动画效果。这些小任务可以像玩家一样掌握控制权,不需要操作系统的干预,这就是协程。协程可以在执行过程中暂停,然后切换到另一个协程,而不需要切换整个线程或进程。
总体来说:
* 进程是独立的程序运行在计算机上。
* 线程是进程内的独立执行单元,共享进程的资源。
* 协程是更轻量级的任务,可以由程序员控制,适用于异步操作和更灵活的任务切换。
---
在 Go 语言中,有一些术语的概念和传统的操作系统中的概念有所不同:
1. **进程 (Process):**
* 在传统的操作系统中,一个进程是独立的执行环境,有自己的内存空间、文件描述符等。
* 在 Go 中,通常来说,一个 Go 进程就是一个正在运行的 Go 程序的实例。
2. **线程 (Thread):**
* 在传统的操作系统中,线程是操作系统调度的最小单位,一个进程可以包含多个线程,它们共享相同的进程资源。
* 在 Go 中,Go 语言的运行时(runtime)会管理一组系统线程,这些线程用于执行 Go 程序的不同部分。Go 运行时会在需要的时候创建或销毁线程,而且开发者一般不直接操作这些线程。
---
- 在传统的操作系统中,线程是程序执行的最小单位。假设你有一个程序,这个程序同时需要完成两个任务:一个任务是下载文件,另一个任务是进行图形界面的更新。在单线程的情况下,你需要等待一个任务完成后再执行另一个任务,因为在同一时间内,CPU 只能执行一个任务。
现在,考虑多线程的情况。你可以创建两个线程,一个负责下载文件,另一个负责更新图形界面。这两个线程可以同时运行,因为它们在不同的线程上。这意味着下载文件的任务可以和更新图形界面的任务并行执行,提高了整体的效率。
3. **协程 (Goroutine):**
* 在传统的操作系统中,线程是由操作系统调度的。线程的创建和销毁开销较大,会占用较多系统资源。
* 在 Go 中,协程是 Go 语言提供的轻量级线程。协程由 Go 运行时调度,而不是由操作系统调度。创建和销毁协程的开销相对较小,因此可以创建大量的协程来处理并发任务。
* 协程的关键特点是它们是由 Go 运行时调度的,而不是由操作系统调度。它们在用户态上执行,不需要操作系统的线程。Go 的协程使用 `go` 关键字创建。
在 Go 中,协程是并发处理的主要手段。它们可以高效地处理大量的并发任务,而不会像传统的线程那样占用大量系统资源。 Go 的调度器可以在多个系统线程上执行协程,这使得 Go 语言在并发编程方面非常强大。
---
进程(Process),线程(Thread),协程(Coroutine)是计算机中用于执行任务的不同执行单元,它们之间有以下主要区别:
- 线程之前的数据通过通过信号或者锁
- 协程可以chanel 来减少竞态条件和死锁的风险
1. **定义**:
* 进程:是独立的执行环境,每个进程有自己的内存空间和系统资源,可以包含多个线程。
* 线程:是进程内的执行单元,共享进程的内存空间和系统资源。
* 协程:是一种轻量级的线程,由用户控制,不依赖于操作系统的线程管理。
2. **资源消耗**:
* 进程:创建和销毁进程较为消耗资源,进程间切换开销较大。
* 线程:创建和销毁线程相对较小,线程间切换开销较小。
* 协程:创建和销毁开销非常小,切换开销也较小。
3. **通信方式**:
* 进程:进程间通信(IPC)通常需要使用操作系统提供的机制,如管道、消息队列、共享内存等。
* 线程:线程间通信较为容易,可以通过共享内存等方式直接通信。
* 协程:协程通信通常通过在特定的位置主动让出执行权,然后切换到另一个协程来实现。
4. **并发性**:
* 进程:进程是独立的,相互不受影响,因此天然支持并发。
* 线程:线程在同一进程内共享内存,需要进行同步操作,以避免数据竞争,因此也支持并发。
* 协程:协程是用户级别的轻量级线程,可以有数千个同时存在,支持大规模并发。
5. **切换开销**:
* 进程:进程切换开销较大,涉及到上下文切换。
* 线程:线程切换开销相对较小,因为共享进程内存。
* 协程:协程切换开销非常小,通常由用户控制。
6. **调度方式**:
* 进程:由操作系统进行进程调度。
* 线程:线程调度可以由操作系统进行,也可以由用户自己进行线程管理。
* 协程:协程调度完全由用户控制,可以实现更灵活的调度策略。
总结:进程是资源独立的执行单元,线程是进程内的执行单元,而协程是用户级别的轻量级线程,具有更小的资源消耗和更灵活的调度方式,通常用于高并发的应用中。不同的任务需求会决定选择使用哪种执行单元。
---
- 进程:是独立的执行环境,每个进程有自己的内存空间和系统资源
- 线程是进程的执行单元, 共享进程的内存空间和系统资源
- Golang
- 切片 slice
- 数组和切片的区别
- 左闭右开
- make([]int, 5) 和 make([]int, 0, 5) 区别
- 切片非线程安全,并发操作为啥不会像map一样报错
- []struct{} 如何遍历
- 切片如何删除某个元素
- append 一个nil 切片
- 哈希表 map
- 并发操作
- 并发写报错
- 并发读不会报错
- 并发读有写报错
- 并发迭代有写报错
- 自制并发安全字典
- 官方并发安全字典
- 对未初始化的 map 进行赋值操作
- map的底层
- 无序输出
- 等量扩容
- 实现集合
- map的key可以使哪些值
- 协程 go
- 协程相关阅读
- 进程、线程、协程
- 协程 (捕获异常 和 协程池)
- GPM 模型
- CSP模型
- channel
- channel 相关操作
- 交替打印
- 如何让channel 只能接收/只能发送
- channel 常见报错
- channel 死锁
- nil channel 和 已关闭的 channel
- 使用 select 来多路复用 channel
- channel 的使用
- 接口和结构体
- 简单使用
- 两个结构体能否比较
- 工厂模式
- 概念
- 简单工厂
- 方法工厂
- 堆和栈,值类型和引用类型,内存逃逸,垃圾回收
- 栈和堆
- 内存逃逸
- 值类型和引用类型
- 垃圾回收方式
- 性能优化分析工具 pprof
- golang 代码片段
- 片段一 defer
- 片段二 channel
- Golang 相关
- Golang 相关阅读
- Golang 1-10
- make 和 new 的区别
- 使用指针的场景
- Go语言的context包
- 位运算
- Copy 是浅拷贝还是深拷贝
- init 函数 和 sync.Once
- select 多路复用
- Golang 其它
- MongoDB
- 可比较类型 与 可转json 类型
- Gorm
- 面向对象和面向过程
- go语言实现-面向对象
- go语言实现-面向过程
- 限流,熔断,降级
- 了解
- 熔断配置
- 熔断例子
- 服务降级
- github.com/alibaba/sentinel-golang
- 互斥锁 读写锁 原子锁
- 为什么需要锁
- 互斥锁
- 读写锁
- 原子锁
- 互斥锁性能对比
- 原子锁性能对比
- 互斥锁 or 原子锁?
- 条件锁
- 计数器
- GoFrame
- GF1.16版本
- 修改使用的表
- 按天、周、月、年
- GoFrame 文档
- 配置文件
- 生成脚本
- 排序算法
- 相关排序
- 冒泡排序
- 选择排序
- 插入排序
- 快速排序
- 归并排序
- 堆排序
- 数据库
- 分布式怎么保证线程安全
- 数据库实现方式
- 基于表记录
- 乐观锁
- 悲观锁
- Redis实现方式
- Zookeeper实现方式
- Mysql 相关
- group_concat
- 索引优化
- 索引优化1
- 定期分析和优化索引
- 覆盖索引
- 组合索引
- 聚簇索引和非聚簇索引
- 索引类型与方式、聚簇与非聚簇索引
- 事务特征和隔离级别
- 查询优化
- mysql自增表插入数据时,Id不连续问题
- InnoDB引擎 和 MyISAM引擎区别
- 锁
- 悲观锁和乐观锁
- 查询,更新,插入语句
- 什么是死锁
- 怎么处理死锁
- MySQL 隔离级别
- 事务特征
- 隔离级别
- 废弃3
- 索引
- 索引类型和方式、聚簇和非聚簇索引(上)
- 索引类型和方式、聚簇和非聚簇索引(下)
- 回表、覆盖索引、最左前缀、联合索引、索引下推、索引合并
- Mysql 优化
- 索引的原理
- 千万级表修改表结构
- Redis
- 获取随机三条数据
- Redis 持久化方式
- 全量模式 RDB 冷备份(内存快照)
- 增量模式 AOF 热备份(文件追加)
- 过期key的删除策略、内存淘汰机制
- 数据结构
- 位图
- 网络
- 网络相关
- 游戏同步方式:帧同步和状态同步
- Websocket
- OSI模型
- TCP 与 UDP
- 三次握手四次挥手
- Http 状态码
- 1xx(信息性状态码)
- 101 服务端代码
- 101 客户端代码
- 2xx(成功状态码)
- 3xx(重定向状态码)
- 302 服务端代码
- 302 客户端代码
- 4xx(客户端错误状态码)
- 5xx(服务器错误状态码)
- 如何排查接口问题
- 网络请求和响应过程
- time_wait
- keep-alive
- http 和 rpc 的区别
- I/O多路复用 select和poll
- too many open file
- 其它技术
- git 相关操作
- 修改提交备注
- 多个提交合并成一个提交
- 回退版本
- 小程序和公众号
- 消息模板
- 获取code
- 静默登录
- 其它技术相关
- C盘空间不足
- 生成式人工智能AIGC
- 共享文件
- 接口文档, mock提供测试数据
- 抓包工具
- Python
- 安装包失败
- 自动化测试 Scrapy
- AIGC:人工智能生成内容
- PHP
- xhprof 性能分析
- 一键安装
- 哈希冲突的解决方式
- 链地址法(拉链法)
- 开放地址法
- 再哈希
- 概念1
- Nginx
- 负载均衡方式
- 加密解密
- 简单了解
- 签名算法例子
- 码例子1
- 代码例子2
- Linux
- netstat (用于查看和管理网络连接和路由表)
- ps 用于查看和管理进程
- ab 压测
- nohup 守护进程
- lsof (List Open File 获取被进程打开文件的信息)
- tail 查看日志
- 各类linux同步机制
- Socket 服务端的实现,select 和epoll的区别?
- scp 传输,awk 是一个强大的文本分析工具
- pidof
- 项目
- 棋牌
- 牌的编码
- 出牌规则
- 洗牌
- 股票
- 股票知识
- 龙虎榜数据缓存方式
- 单日龙虎榜数据
- 单只股票的历史上榜
- 遇到的问题
- 浮点数精度问题
- Mysql Sum 精度问题(float, double精度问题)
- 分页问题(数据重复)
- 工具包
- v3
- common.go
- common_test.go
- customized.go
- customized_test.go
- slice.go
- slice_test.go
- time.go
- time_test.go
- v4
- common.go
- common_test.go
- customized.go
- customized_test.go
- slice.go
- time.go
- time_test.go
- 相关阅读
- 集合 map
- 协程 goroutine
- 通道 channel
- json 和 gob 序列化和反序列化
- redis 有序集合
- 相关阅读 s
- pyTorch
- defer
- 内存泄漏
- 数据传输
- 杂项
- 一提