> # 進程、線程、協程
**進程**:操作系統中資源分配的基本單位,每個進程有獨立的內存空間。進程間隔離較好,但切換開銷大。
**線程**:進程中的執行單元,同一進程的線程共享內存和資源。線程比進程輕量,切換開銷較小,但需要手動管理同步。
**協程**:比線程更輕量級的執行單元,由用戶態調度管理。協程的調度由程序自行控制,性能開銷更低,適合大量并發場景。
- 進程:有自己的內存空間和系統資源, 上下文進程切換開銷大
- 線程:一個進程可以有多個線程,線程共享進程的內存和資源, 上下文切換開銷較小
- 協程:一個線程可以有多個協程,協程是一種用戶態的輕量級線程,上下文切換開銷小,調度由用戶控制
---
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
- 相關閱讀
- 協程 goroutine
- 通道 channel
- json 和 gob 序列化和反序列化
- redis 有序集合
- mysql22
- 相關閱讀 s
- pyTorch
- defer
- 內存泄漏
- 數據傳輸
- 雜項
- 一提
- gogogoo
- 內容