【多線程】進程與線程

🏀🏀🏀來都來了,不妨點個關注!
🎧🎧🎧博客主頁:歡迎各位大佬!
在這里插入圖片描述

文章目錄

  • 1. 操作系統
    • 1.1 什么是操作系統
    • 1.2 操作系統主要的功能
  • 2. 進程
    • 2.1 什么是進程
    • 2.2 通過PCB描述一個進程
    • 2.3 進程的調度
    • 2.4 PCB的管理
    • 2.5 內存管理
    • 2.6 進程間通信的方式
  • 3.線程
    • 3.1 什么是線程
    • 3.2 有了進程為什么還要有線程
    • 3.3 進程與線程的聯系和區別

1. 操作系統

1.1 什么是操作系統

操作系統本質上是運行在計算機上的軟件程序,對上,它負責給軟件運行提供穩定的環境,對下,它要管理好各種硬件設備。我們可以通過以下的圖文進行理解:

在這里插入圖片描述

1.2 操作系統主要的功能

從資源管理的角度來看,操作系統主要有六大功能:

  • 進程和線程的管理:進程的創建、撤銷、阻塞、喚醒,進程間的通信等。
  • 存儲管理:內存的分配和管理、外存(磁盤等)的分配和管理等。
  • 文件管理:文件的讀、寫、創建及刪除等。
  • 設備管理:完成設備(輸入輸出設備和外部存儲設備等)的請求或釋放,以及設備啟動等功能。
  • 網絡管理:操作系統負責管理計算機網絡的使用。網絡是計算機系統中連接不同計算機的方式,操作系統需要管理計算機網絡的配置、連接、通信和安全等,以提供高效可靠的網絡服務。
  • 安全管理:用戶的身份認證、訪問控制、文件加密等,以防止非法用戶對系統資源的訪問和操作。

可以看到操作系統的上述功能中,進程和線程管理和我們今天要講的進程與線程關系密切。
那么為什么要進行進程的管理呢,那當然是因為進程太多了才需要管理嘛,就比如我們上學,學校也都有會一個學生管理系統,里面就記錄著我們每個學生的信息。下面我們分別從進程和線程兩個角度進行講解。

2. 進程

2.1 什么是進程

一個運行起來的程序就是進程,而我們電腦中的.exe文件就是一個可執行的文件(程序),當雙擊這個.exe文件,這個程序跑起來就形成了一個進程。關于這個我們可以通過任務管理器查看,如下圖:
在這里插入圖片描述
在這里插入圖片描述
我們從上面兩種圖都可以觀察到我們的計算機上運行著許許多多的進程,我們在最開始提到過,操作系統的一大功能就是進行進程的管理,那么它是如何對進程進行管理的呢?其實就分為兩步,下面我們就來介紹:

  1. 描述一個進程:使用結構體/類把一個進程有哪些信息描述出來
  2. 組織這些進程:使用一定的數據結構將這些結構體/對象組織在一起

2.2 通過PCB描述一個進程

在上面我們提到對進程管理分為了兩步,第一步就是描述該進程,而在操作系統中,用于描述系統進程狀態的數據結構通常被稱為進程控制塊(Process Control Block, PCB)。而PCB有很多的屬性,這里我們將介紹幾個核心的:

  1. pid: 進程的唯一身份標識(這個我們在Linux常用命令章節里提到過)
  2. 內存指針:表示當前進程使用的內存是哪一部分(進程要運行起來就需要消耗一些硬件資源,這其中就包括了內存)
  3. 文件描述符表:文件描述符表是一個數據結構,用于記錄當前進程打開了哪些文件。當進程需要操作文件時,它會在文件描述符表中分配一個表項,并構造一個結構體來描述該文件的相關信息。
  4. 進程狀態:描述當前進程所處的狀態
    主要為兩個狀態:
    就緒態:該進程已經準備好了,隨時可以在CPU上運行
    阻塞態:該進程暫時無法在CPU上運行
  5. 進程的優先級:優先級用于決定操作系統調度進程的順序。優先級高的進程會獲得更多的CPU資源
  6. 進程的上下文:進程的上下文就是記錄當前進程執行到哪里的"存檔記錄",進程在離開CPU的時候就需要把進程執行的中間結果進行"存檔",等下一次回到CPU上的時候再恢復之前的"存檔"。從上一次的結果繼續往后面執行。(類似于我們玩游戲玩到一半不玩了進行存檔退出,下一次玩的時候再進行讀檔,回到之前玩的地方繼續往后面玩)
  7. 進程的記賬信息:統計了每個進程在CPU上執行了多久了,可以作為進程調度的參考依據

其中,第4、5、6,7點都是和進程的調度有關的,下面我們先來介紹一些什么是進程的調度

2.3 進程的調度

在計算機操作系統中,進程調度是指按照某種策略或算法,從就緒隊列中選擇一個進程,將處理機分配給該進程,使之執行的過程。
那為什么要有進程的調度呢
我們先來了解一下CPU,我們的一個個程序能夠運行起來,都是依靠著CPU的調度,我們可以打開任務管理器來看看CPU的相關屬性,如下圖:
在這里插入圖片描述

這個表示我自己計算機的CPU有8個 物理核心,而一個物理核心相當于兩個邏輯核心,這表示CPU同時能處理16個任務,此時就有人想問了但我們的計算機上同時運行的進程可不止16個,那CPU是如何處理的呢?這里我們介紹兩個核心概念

  • 并行:兩個核心同時執行兩個任務(進程),此時這兩個任務就是并行執行的。
  • 并發: 一個核心先運行進程1運行一會后再運行進程2運行一會后再運行進程3,只有切換的夠快,這里的進程1、2,3看起來就像是同時執行的一樣。
    這也就告訴我們,雖然我的CPU只能同時執行16個任務,但通過并行+并發,我們就可以同時處理多個任務了,通常我們也將這里的并行+并發統稱為并發。

2.4 PCB的管理

操作系統往往是使用雙向鏈表的方式將PCB組織起來,這樣進程相當于鏈表中的節點,方便管理時進行增刪改查的操作

  1. 創建一個進程,即創建一個鏈表的節點
  2. 銷毀一個進程,即把鏈表的節點刪除
  3. 遍歷進程列表,即遍歷鏈表

2.5 內存管理

操作系統對內存資源的分配,采用的是空間模式 —— 不同進程使用內存中的不同區域,互相之間不會干擾。
而操作系統給每一個進程分配的內存空間都是以“虛擬地址空間”的方式分配的。
這里肯定就會有人要問了,有直接的物理地址,為什么不直接給每一個進程直接分配物理地址。我們用下面進程直接訪問實際物理地址的圖片來介紹:
在這里插入圖片描述

上圖就是每個進程都是直接訪問物理內存的地址,此時可能就會產生一個比較嚴重的問題,萬一進程1的代碼出現了bug(比如數組下標越界,野指針…),可能就會連帶著把進程2搞崩潰了。
下面我們就來看看操作系統是如何通過使用虛擬內存來解決這個問題的:
在這里插入圖片描述

站在進程自身的角度看,它們的內存地址就是0x00aa-0x00ff,這里訪問的內存地址就會被操作系統自動映射到真正的物理地址上,但是進程自身是感知不到實際的物理地址是啥的。
此時如果進程1代碼出bug,就沒有什么影響,因為任何一個內存操作都需要通過頁表翻譯,比如出現野指針0x11aa,拿著這個地址,頁表無法映射也就不會修改真正物理內存,即不會對進程2的內存數據進行干擾。

  • 頁表:操作系統使用頁表來維護虛擬地址到物理地址的映射關系。頁表是一種數據結構,它記錄了每個虛擬頁(通常是4KB大小)對應的物理頁號。
  • 地址翻譯:當CPU執行指令并需要訪問某個內存地址時,它首先會檢查這個地址是虛擬地址還是物理地址。如果是虛擬地址,CPU會通過頁表將其轉換為物理地址,然后訪問物理內存。
  • 缺頁異常:如果CPU在訪問某個虛擬頁時發現該頁沒有在物理內存中(即發生了缺頁),它會產生一個缺頁異常。操作系統會捕獲這個異常,并從磁盤或其他存儲介質中加載缺失的頁到物理內存中,然后更新頁表以反映這一變化。

2.6 進程間通信的方式

在上面我們說了操作系統給每個進程都分配了一塊獨立的虛擬地址空間,這保證了進程間的地址空間隔離。一個進程無法直接訪問另一個進程的內存,從而避免了內存沖突和數據損壞。
即各個進程互相之間是無法感受到對方存在的,是相互獨立的,這樣進程之間互相具備"隔離性",但有時候需要進程之間進行交互,相互配合。
此時就有了進程間的通信:即在隔離性前提下,找一個公共區域,讓進程借助這個區域完成數據交換。
目前,主流操作系統提供的進程通信機制有如下:

  1. 管道
  2. 共享內存
  3. 文件
  4. 網絡
  5. 信號量
  6. 信號
  7. 套接字(Sockets)

其中,網絡是一種相對特殊的 IPC 機制,它除了支持同主機兩個進程間通信,還支持同一網絡內部非同一主機上的進程間進行通信。

3.線程

3.1 什么是線程

線程(Thread) 也被稱為輕量級進程,更加輕量。多個線程可以在同一個進程中同時執行,并且共享進程的資源比如內存空間、文件句柄、網絡連接等。舉例:你打開的微信里就有一個線程專門用來拉取別人發你的最新的消息。

3.2 有了進程為什么還要有線程

  • 進程切換是一個開銷很大的操作,線程切換的成本較低。
  • 線程更輕量,一個進程可以創建多個線程。
  • 多個線程可以并發處理不同的任務,更有效地利用了多處理器和多核計算機。而進程只能在一個時間干一件事,如果在執行過程中遇到阻塞問題比如 IO 阻塞就會掛起直到結果返回。
  • 同一進程內的線程共享內存和文件,因此它們之間相互通信無須調用內核。

3.3 進程與線程的聯系和區別

聯系:一個進程中可以有多個線程,這些線程共享一份堆和方法區(jdk1.8之后稱為元數據區)資源,同時每個線程有自己的虛擬機棧、本地方法棧和程序計數器。這點我們在JVM篇里介紹過。

區別

  1. 進程是操作系統資源分配的基本單位,線程是操作系統調度執行的基本單位(這也告訴我們上述我們介紹的進程的調度,其實是對進程里的線程的調度)
  2. 進程具有獨立性,一個進程不會影響另一個進程,但在同一進程的多個線程之間,一個線程掛了,可能會把整個線程帶走,影響其它線程。
  3. 進程開銷大,消耗資源多,線程執行開銷小,但不利于資源的管理和保護

本次的分享就結束了,感謝支持!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/41086.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/41086.shtml
英文地址,請注明出處:http://en.pswp.cn/web/41086.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

jEasyUI 創建菜單按鈕

jEasyUI 創建菜單按鈕 jEasyUI(jQuery EasyUI)是一個基于jQuery的用戶界面插件集合,它為用戶提供了一系列的UI組件,如菜單、按鈕、表格等,以簡化Web頁面的開發過程。在本文中,我們將重點介紹如何使用jEasyUI創建菜單按鈕。 1. 環境準備 在開始之前,請確保您的開發環境…

使用Python繪制甘特圖

使用Python繪制甘特圖 甘特圖效果代碼 甘特圖 甘特圖是一種項目管理工具,用于展示項目進度和任務安排。它通過條狀圖形表示各任務的起止時間,便于直觀地查看項目的各個任務的進度和相互關系。 效果 [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片…

(void) (_x == _y)的作用

在閱讀宋寶華的《Linux設備驅動開發詳解》一書時&#xff0c;看到下面這段代碼&#xff1a; #define min(x, y) ({ \ const typeof(x) _x (x); \ const typeof(y) -y (y); \ (void) (&_x &_y); \ _x < _y ? _x : _y; }) 這段代碼可以理解如…

變量和標識符

一、變量 變量 數據類型 變量名初始值 常量的定義方式 1.#define 宏常量 (Day是常量&#xff0c;一旦修改就會報錯) /2.const修飾的變量 #include <iostream> using namespace std; //變量 數據類型 變量名初始值 //常量的定義方式 //1.#define 宏常量 (Day是常量&…

Vue.js 基礎入門指南

前言 在前端開發的廣闊領域中&#xff0c;Vue.js 無疑是一顆璀璨的明星&#xff0c;以其漸進式框架的特性吸引了無數開發者的目光。Vue.js 旨在通過簡潔的 API 實現響應式的數據綁定和組合的視圖組件&#xff0c;使得構建用戶界面變得既快速又簡單。本文將帶你走進 Vue.js 的世…

學習探索RASP:下一代應用安全防護技術

在當今數字化浪潮中&#xff0c;各類信息系統、應用程序不僅是企業數字化轉型的驅動力&#xff0c;也成為了網絡攻擊的集中地帶。面對日益復雜多變的網絡安全威脅&#xff0c;防火墻等傳統防護手段逐漸顯得力不從心。在此背景下&#xff0c;尋求一種更為智能、高效且能深度融入…

代碼隨想錄算法訓練營第22天|LeetCode 77. 組合、216.組合總和III、17.電話號碼的字母組合

1. LeetCode 77. 組合 題目鏈接&#xff1a;https://leetcode.cn/problems/combinations/description/ 文章鏈接&#xff1a;https://programmercarl.com/0077.組合.html 視頻鏈接&#xff1a;https://www.bilibili.com/video/BV1ti4y1L7cv 思路&#xff1a;利用遞歸回溯的方式…

Codeforces Round 954 (Div. 3)

這里寫自定義目錄標題 A. X Axis題意&#xff1a;題解&#xff1a;代碼&#xff1a; B. Matrix Stabilization題意&#xff1a;題解&#xff1a;代碼&#xff1a; C. Update Queries題意&#xff1a;題解&#xff1a;代碼&#xff1a; D. Mathematical Problem題意&#xff1a;…

nanodiffusion代碼逐行理解之diffusion

目錄 一、diffusion創建二、GaussianDiffusion定義三、代碼理解def __init__(self,model,img_size,img_channels,num_classes,betas, loss_type"l2", ema_decay0.9999, ema_start5000, ema_update_rate1,):def remove_noise(self, x, t, y, use_emaTrue):def sample(…

MySQL 集群

MySQL 集群有多種類型&#xff0c;每種類型都有其特定的用途和優勢。以下是一些常見的 MySQL 集群解決方案&#xff1a; 1. MySQL Replication 描述&#xff1a;MySQL 復制是一種異步復制機制&#xff0c;允許將一個 MySQL 數據庫的數據復制到一個或多個從服務器。 用途&…

bug——多重定義

bug——多重定義 你的問題是在C代碼中遇到了"reference to data is ambiguous"的錯誤。這個錯誤通常發生在你嘗試引用一個具有多重定義的變量時。 在你的代碼中&#xff0c;你定義了一個全局變量data&#xff0c;同時&#xff0c;C標準庫中也有一個名為data的函數模板…

【云原生】Kubernetes部署高可用平臺手冊

部署Kubernetes高可用平臺 文章目錄 部署Kubernetes高可用平臺基礎環境一、基礎環境配置1.1、關閉Swap1.2、添加hosts解析1.3、橋接IPv4流量傳遞到iptables的鏈 二、配置Kubernetes的VIP2.1、安裝Nginx2.2、修改Nginx配置文件2.3、啟動服務2.4、安裝Keepalived2.5、修改配置文件…

Linux 定時任務詳解:全面掌握 cron 和 at 命令

Linux 定時任務詳解&#xff1a;全面掌握 cron 和 at 命令 Linux 系統中定時任務的管理對于運維和開發人員來說都是至關重要的。通過定時任務&#xff0c;可以在特定時間自動執行腳本或命令&#xff0c;提高系統自動化程度。本文將詳細介紹 Linux 中常用的定時任務管理工具 cr…

一拖二快充線:生活充電新風尚,高效便捷解決雙設備充電難題

一拖二快充線在生活應用領域的優勢與雙接充電的便攜性問題 在現代快節奏的生活中&#xff0c;電子設備已成為我們不可或缺的日常伴侶。無論是智能手機、平板電腦還是筆記本電腦&#xff0c;它們在我們的工作、學習和娛樂中扮演著至關重要的角色。然而&#xff0c;隨著設備數量…

優化:遍歷List循環查找數據庫導致接口過慢問題

前提&#xff1a; 我們在寫查詢的時候&#xff0c;有時候會遇到多表聯查&#xff0c;一遇到多表聯查大家就會直接寫sql語句&#xff0c;不會使用較為方便的LambdaQueryWrapper去查詢了。作為一個2024新進入碼農世界的小白&#xff0c;我喜歡使用LambdaQueryWrapper&#xff0c;…

產品經理系列1—如何實現一個電商系統

具體筆記如下&#xff0c;主要按獲客—找貨—下單—售后四個部分進行模塊拆解

代碼隨想錄算法訓練Day58|LeetCode417-太平洋大西洋水流問題、LeetCode827-最大人工島

太平洋大西洋水流問題 力扣417-太平洋大西洋水流問題 有一個 m n 的矩形島嶼&#xff0c;與 太平洋 和 大西洋 相鄰。 “太平洋” 處于大陸的左邊界和上邊界&#xff0c;而 “大西洋” 處于大陸的右邊界和下邊界。 這個島被分割成一個由若干方形單元格組成的網格。給定一個…

用 Emacs 寫代碼有哪些值得推薦的插件

以下是一些用于 Emacs 寫代碼的值得推薦的插件&#xff1a; Ido-mode&#xff1a;交互式操作模式&#xff0c;它用列出當前目錄所有文件的列表來取代常規的打開文件提示符&#xff0c;能讓操作更可視化&#xff0c;快速遍歷文件。Smex&#xff1a;可替代普通的 M-x 提示符&…

【Unity】unity學習掃盲知識點

1、建議檢查下SystemInfo的引用。這個是什么 Unity的SystemInfo類提供了一種獲取關于當前硬件和操作系統的信息的方法。這包括設備類型&#xff0c;操作系統&#xff0c;處理器&#xff0c;內存&#xff0c;顯卡&#xff0c;支持的Unity特性等。使用SystemInfo類非常簡單。它的…

【python】生成完全數

定義 如果一個數恰好等于它的真因子之和&#xff0c;則稱該數為“完全數” [2]。各個小于它的約數&#xff08;真約數&#xff0c;列出某數的約數&#xff0c;去掉該數本身&#xff0c;剩下的就是它的真約數&#xff09;的和等于它本身的自然數叫做完全數&#xff08;Perfect …