操作系統(tǒng)基礎(chǔ)之進(jìn)程管理

進(jìn)程管理

進(jìn)程相關(guān)的基本概念

  • 進(jìn)程是多處理程序中作為資源分配和獨(dú)立運(yùn)行的基本單位,進(jìn)程實(shí)體由程序段、數(shù)據(jù)段、PCB三個(gè)部分組成,引入進(jìn)程的目的是為了使進(jìn)程實(shí)體能和其他進(jìn)程實(shí)體并發(fā)執(zhí)行
  • 進(jìn)程的三種基本狀態(tài):就緒狀態(tài)、執(zhí)行狀態(tài)、阻塞狀態(tài)
  • 引入線程的目的:使得多個(gè)程序能并發(fā)執(zhí)行,以提高資源利用率以及系統(tǒng)吞吐量
  • 程序順序執(zhí)行的要求
    • 順序性:程序按照次序逐步執(zhí)行
    • 封閉性:獨(dú)占全機(jī)資源
    • 可再現(xiàn)性:直接結(jié)果不變
  • 并發(fā)執(zhí)行的特征
    • 間斷性:多個(gè)程序相互制約
    • 失去封閉性:多個(gè)程序共享資源
    • 不可再現(xiàn)性:執(zhí)行結(jié)果受其他因素干擾
  • 進(jìn)程的特征
    • 結(jié)構(gòu)性:進(jìn)程由數(shù)據(jù)段、程序段、PCB構(gòu)成
    • 動(dòng)態(tài)性:進(jìn)程可以被動(dòng)態(tài)地創(chuàng)建、執(zhí)行、撤銷
    • 并發(fā)性:同一時(shí)間內(nèi)有多個(gè)進(jìn)程在運(yùn)行
    • 獨(dú)立性:是獨(dú)立運(yùn)行以及獲得資源的基本單位
    • 異步性:異步執(zhí)行

進(jìn)程控制塊

進(jìn)程控制塊是用于描述和控制進(jìn)程的運(yùn)行而定義的一個(gè)數(shù)據(jù)結(jié)構(gòu),系統(tǒng)總是根據(jù)PCB來(lái)對(duì)并發(fā)執(zhí)行的進(jìn)程進(jìn)行控制以及管理,也就是系統(tǒng)是根據(jù)PCB來(lái)感知進(jìn)程的存在的,PCB是進(jìn)程存在的唯一標(biāo)識(shí)

進(jìn)程控制塊主要包含以下信息

  • 進(jìn)程標(biāo)識(shí)符:用于唯一標(biāo)識(shí)一個(gè)進(jìn)程
  • 處理機(jī)狀態(tài):主要為處理機(jī)的各種寄存器(通用寄存器、指令寄存器、程序狀態(tài)寄存器、用戶棧指針)中的內(nèi)容
  • 進(jìn)程調(diào)度信息:進(jìn)程狀態(tài)、進(jìn)程優(yōu)先級(jí)、進(jìn)程調(diào)度所需要的其他信息、阻塞事件
  • 進(jìn)程控制信息:程序以及數(shù)據(jù)的地址、進(jìn)程同步和通信機(jī)制、資源清單、鏈接指針

進(jìn)程控制塊的組織形式

  • 線性表方式:所有進(jìn)程都放在同一個(gè)線性表中
    • 優(yōu)點(diǎn):簡(jiǎn)單
    • 缺點(diǎn):必須掃描整個(gè)進(jìn)程表
    • 應(yīng)用場(chǎng)景:進(jìn)程少的系統(tǒng)
  • 鏈接方式:根據(jù)線程的狀態(tài)將其放在不同的鏈接隊(duì)列中(執(zhí)行隊(duì)列、就緒隊(duì)列...)
  • 索引方式:根據(jù)線程的狀態(tài),將相同狀態(tài)的線程在鏈表中的首地址整理成索引表

進(jìn)程的控制

進(jìn)程控制主要的操作為:創(chuàng)建一個(gè)新進(jìn)程、終止一個(gè)已經(jīng)完成的進(jìn)程、終止一個(gè)因其他原因而無(wú)法繼續(xù)執(zhí)行的進(jìn)程、進(jìn)程的狀態(tài)轉(zhuǎn)換

進(jìn)程的控制主要由內(nèi)核的原語(yǔ)來(lái)實(shí)現(xiàn),所謂原語(yǔ)就是一連串的操作指令,但是這些指令整體構(gòu)成一個(gè)操作,要么都做,要么都不做,也就是所謂的原子操作

進(jìn)程的創(chuàng)建

  • 使用進(jìn)程樹來(lái)描述進(jìn)程之間的關(guān)系
  • 子進(jìn)程可以繼承父進(jìn)程所擁有的資源,撤銷子進(jìn)程時(shí),把從父進(jìn)程中得到的東西歸還給父進(jìn)程
  • 撤銷父進(jìn)程時(shí),也必須同時(shí)撤銷其所有的子進(jìn)程

引起進(jìn)程創(chuàng)建的事件

  • 用戶登錄
  • 作業(yè)調(diào)度
  • 提供服務(wù)
  • 應(yīng)用請(qǐng)求

進(jìn)程創(chuàng)建過(guò)程

  1. 申請(qǐng)空白PCB
  2. 為新進(jìn)程分配資源
  3. 初始化進(jìn)程控制塊
  4. 將新進(jìn)程插入就緒隊(duì)列

進(jìn)程的終止

進(jìn)程終止事件

  • 正常結(jié)束
  • 異常結(jié)束
    • 越界錯(cuò)誤
    • 保護(hù)錯(cuò)
    • 非法指令
    • 特權(quán)指令錯(cuò)誤
    • 運(yùn)行超時(shí)
    • 等待超時(shí)
    • 運(yùn)算錯(cuò)誤
    • IO故障
  • 外界干擾
    • 操作員或操作系統(tǒng)干預(yù)
    • 父進(jìn)程請(qǐng)求(父進(jìn)程具有終止任何子進(jìn)程的權(quán)力)
    • 父進(jìn)程終止

進(jìn)程終止過(guò)程

  1. 根據(jù)終止進(jìn)程的標(biāo)識(shí)符,從PCB中檢索出該進(jìn)程的PCB,從中讀出進(jìn)程的狀態(tài)
  2. 若被終止的進(jìn)程處于執(zhí)行狀態(tài),則立即終止其執(zhí)行
  3. 終止進(jìn)程的所有子孫進(jìn)程
  4. 回收被終止的進(jìn)程的全部資源
  5. 將被終止的進(jìn)程從所在隊(duì)列中移出

進(jìn)程的阻塞與喚醒

引起阻塞的事件

  • 請(qǐng)求系統(tǒng)服務(wù)
  • 啟動(dòng)某種操作
  • 新數(shù)據(jù)尚未到達(dá)
  • 無(wú)新工作可以做

阻塞過(guò)程

  1. 保留現(xiàn)場(chǎng)信息
  2. 更改線程狀態(tài)
  3. 加入阻塞隊(duì)列
  4. 進(jìn)程調(diào)度

引起喚醒的事件

  • 請(qǐng)求的資源準(zhǔn)備完成
  • 某種操作者完成
  • 新數(shù)據(jù)已經(jīng)到達(dá)
  • 有新的工作

喚醒過(guò)程

  1. 將進(jìn)程從阻塞隊(duì)列移出
  2. 更改進(jìn)程狀態(tài)(靜止阻塞 --> 活動(dòng)阻塞 靜止就緒 --> 活動(dòng)就緒)

進(jìn)程的掛起與激活

掛起過(guò)程

  1. 更改進(jìn)程狀態(tài)
  2. 將數(shù)據(jù)復(fù)制到外存
  3. 歸還內(nèi)存

激活過(guò)程

  1. 重新申請(qǐng)資源
  2. 將數(shù)據(jù)調(diào)入內(nèi)存
  3. 恢復(fù)線程狀態(tài)

進(jìn)程同步

進(jìn)程間的關(guān)系

  • 相互合作關(guān)系(直接相互約束)
  • 資源共享關(guān)系(間接相互約束)

進(jìn)程同步的主要任務(wù)是對(duì)多個(gè)相關(guān)進(jìn)程在執(zhí)行次序上進(jìn)行協(xié)調(diào),以使并發(fā)執(zhí)行的諸進(jìn)程之間能有效地共享資源和相互合作,從而使程序的執(zhí)行具有可再現(xiàn)性

臨界資源:同一時(shí)刻只能被一個(gè)進(jìn)程使用的資源(硬件資源、軟件資源),臨界資源只能使用互斥訪問(wèn)方式,也就是只能一個(gè)進(jìn)程使用完之后才給另一個(gè)進(jìn)程使用

臨界區(qū):每個(gè)進(jìn)程中訪問(wèn)臨界資源的那段代碼稱為臨界區(qū)

臨界資源使用的同步原則:

  • 空閑讓進(jìn)(提高效率)
  • 忙則等待(互斥訪問(wèn))
  • 有限等待(避免死鎖)
  • 讓權(quán)等待(放棄占用CPU,避免忙等,浪費(fèi)資源)

信號(hào)量機(jī)制

信號(hào)量是一種特殊的變量,只有兩種基本的原子操作,等待wait(S),也稱為P操作,發(fā)信號(hào)signal(S),也稱為V操作

信號(hào)量是一種有效的進(jìn)程同步工具,從整型信號(hào)量發(fā)展到記錄型信號(hào)量到信號(hào)量集

  • 整型信號(hào)量:用于表示資源數(shù)目,除了初始化之外,僅有兩個(gè)標(biāo)準(zhǔn)的原子操作:wait(S)和signal(S) 也分別稱為P、V操作,采用"忙等"
  • 記錄型信號(hào)量:采用讓權(quán)等待,有一個(gè)表示資源數(shù)量的value以及一個(gè)進(jìn)程鏈表L,用于存放所有等待的進(jìn)程 wait(s) lock(s.L) signal(s) wakeup(s.L)
  • AND型信號(hào)量:將進(jìn)程在整個(gè)運(yùn)行過(guò)程中需要的所有資源,一次性全部分配給進(jìn)程,待進(jìn)程使用完后再一起釋放,只要尚有一個(gè)資源未能分配給進(jìn)程,其他所有可能為之分配的資源也不分配給他Swait(s1, s2, s3, ...) Ssignal(s1, s2, s3, ...)
  • 信號(hào)量集:一次性可以申請(qǐng)一個(gè)資源n份 Swait(s1, t1, d1, s2, t2, d2 ...) d為需求值,t為下限值 Ssignal(s1, d1, ...)

信號(hào)量的應(yīng)用:

  • 實(shí)現(xiàn)進(jìn)程互斥
  • 實(shí)現(xiàn)前驅(qū)關(guān)系(先signal 然后再wait, 這樣就能實(shí)現(xiàn)wait后面的操作后執(zhí)行)

管程機(jī)制

信號(hào)量雖然有效,但是要求每個(gè)訪問(wèn)臨界資源的進(jìn)程都自備同步操作,會(huì)使得大量的同步操作分散在各個(gè)進(jìn)程中,不便于管理,也容易造成死鎖,于是引進(jìn)了新的進(jìn)程同步工具管程

管程:代表共享資源的數(shù)據(jù)結(jié)構(gòu),以及由對(duì)該共享數(shù)據(jù)結(jié)構(gòu)實(shí)施操作的一組過(guò)程所組成的資源管理程序,共同構(gòu)成一個(gè)操作系統(tǒng)的資源管理模塊

管程的組成:

  • 管程的名稱
  • 局部于管程內(nèi)部的共享數(shù)據(jù)結(jié)構(gòu)說(shuō)明
  • 對(duì)該數(shù)據(jù)結(jié)構(gòu)進(jìn)行操作的一組過(guò)程
  • 對(duì)局部于管程內(nèi)部的共享數(shù)據(jù)結(jié)構(gòu)設(shè)置初始值的語(yǔ)句

條件變量:管程內(nèi)部可以根據(jù)需要設(shè)置多個(gè)多個(gè)同步變量,如果管程中的進(jìn)程因?yàn)榈却龡l件x,則執(zhí)行 x.wait,并且加入x隊(duì)列,將管程控制權(quán)交給其他進(jìn)程,若條件x到達(dá),執(zhí)行x.signal

經(jīng)典的進(jìn)程同步問(wèn)題

生產(chǎn)者-消費(fèi)者問(wèn)題

問(wèn)題描述

生產(chǎn)者消費(fèi)者模型描述的是,有一個(gè)以上的生產(chǎn)者在生產(chǎn)物品,并將產(chǎn)生的物品放在一個(gè)緩沖區(qū)中,還有另外一個(gè)以上的消費(fèi)者,消費(fèi)者從緩沖區(qū)中取出物品。這里總共涉及到三個(gè)需要同步的地方:緩沖區(qū)同時(shí)只能被一個(gè)進(jìn)程訪問(wèn)(生產(chǎn)者或者消費(fèi)者);當(dāng)緩沖區(qū)滿時(shí),生產(chǎn)者不能在往其中放數(shù)據(jù),只能等;當(dāng)緩沖區(qū)為空時(shí),消費(fèi)者不能從中取數(shù)據(jù),只能等

偽代碼的描述

  var mutex, full, empty:semaphore:= 1, 0, n
  buffer: array[0, ..., n-1]:=item
  in, out:int = 0, 0

  procedure producer:
  begin
    repeat
      生產(chǎn)一個(gè)產(chǎn)品 item
      wait(empty);
      wait(mutex);
      buffer(in) = item;
      in: = (in + 1) mod n;
      signal(mutex);
      signal(full);
    until false;
  end

  procedure customer:
  begin 
    repeat 
      wait(full);
      wait(mutex);
      item = buffer(out);
      out:= (out + 1) mod n;
      signal(mutext);
      signal(empty);
    until false;
  end

這里需要注意的是,必須先獲得空余/有物品之后再看時(shí)候能進(jìn)入緩沖區(qū),反之會(huì)造成死鎖,原因如下:以生產(chǎn)者為例,先獲得緩沖區(qū)訪問(wèn)權(quán),然后查看緩沖區(qū)是否滿,此時(shí)如果緩沖區(qū)已滿,則生產(chǎn)者會(huì)阻塞,但此時(shí)生產(chǎn)者已經(jīng)獲得了緩沖區(qū)的訪問(wèn)權(quán),所以其他的進(jìn)程均無(wú)法獲得緩沖區(qū)的訪問(wèn)權(quán),進(jìn)而無(wú)法進(jìn)行消費(fèi)(消費(fèi)者),所以造成了死鎖

生產(chǎn)者消費(fèi)者具體實(shí)現(xiàn)

基于信號(hào)量的實(shí)現(xiàn)

package cn.xuhuanfeng.cs;

import java.util.concurrent.Semaphore;

/**
 * Created by Huanfeng.Xu on 2017-06-19.
 *
 * 使用記錄型信號(hào)量來(lái)實(shí)現(xiàn)生產(chǎn)者消費(fèi)者模型
 */
public class Exp1 {
    public static void main(String[] args) {
        Buf buf = new Buf();
        Thread producer = new Thread(new Producer(buf));
        Thread customer = new Thread(new Customer(buf));

        producer.start();
        customer.start();
    }
}


/**
 * 生產(chǎn)者
 */
class Producer implements Runnable{

    private Buf buf;

    public Producer(Buf buf) {
        this.buf = buf;
    }

    @Override
    public void run() {
         int num = 0;
        while (true){
            try {
                buf.add(num);
                System.out.printf("Produce item %d\n", num++);
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

/**
 * 消費(fèi)者
 */
class Customer implements Runnable{

    private Buf buf;

    public Customer(Buf buf) {
        this.buf = buf;
    }

    @Override
    public void run() {
        while (true){
            try {
                int item = buf.get();
                System.out.printf("Get item %d\n", item);
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

/**
 * 緩沖區(qū),生成者將產(chǎn)生的數(shù)據(jù)放在這里,消費(fèi)者從這里獲取數(shù)據(jù)
 */
class Buf{

    private final int SIZE = 10;
    /*
    使用concurrent包所提供的信號(hào)量機(jī)制
    */
    private final Semaphore MUTEX = new Semaphore(1);
    private final Semaphore FULL = new Semaphore(0);
    private final Semaphore EMPTY = new Semaphore(SIZE);
    private int[] data = new int[SIZE];
    private int in, out;

    public Buf() {
        in = 0;
        out = 0;
    }

    public void add(int item) throws InterruptedException {

        /*
        請(qǐng)求資源
         */
        EMPTY.acquire();
        MUTEX.acquire();

        data[in++] = item;
        in %= SIZE;

        /*
        釋放資源
         */
        MUTEX.release();
        FULL.release();
    }

    public int get() throws InterruptedException {

        FULL.acquire();
        MUTEX.acquire();

        int item = data[out++];

        out %= SIZE;

        MUTEX.release();
        EMPTY.release();

        return item;
    }

}


基于信號(hào)的管程實(shí)現(xiàn)

這里需要注意的是,上面的實(shí)現(xiàn)方式并不是管程,而只是普通的使用信號(hào)量而已,只不過(guò)我們把具體操作都封裝起來(lái)了,但是本質(zhì)上不是管程,原因是管程同時(shí)只能有一個(gè)進(jìn)程進(jìn)程訪問(wèn),但是上面的內(nèi)容中,其實(shí)是可以有多個(gè)進(jìn)程同時(shí)進(jìn)行g(shù)et()、add()操作的,下面的代碼展示了使用信號(hào)來(lái)實(shí)現(xiàn),這種方式理論上屬于管程。


/**
 * 基于管程實(shí)現(xiàn)的緩沖區(qū)
 * 使用synchronized來(lái)進(jìn)行同步操作,保證同時(shí)只有
 * 一個(gè)進(jìn)程在訪問(wèn)
 */
class Buf{

    private final int SIZE = 10;
    private int[] data = new int[SIZE];
    private int in;
    private int out;
    private int count;

    public Buf() {
        in = 0;
        out = 0;
        count = 0;
    }

    public synchronized void add(int item) throws InterruptedException {

        /*
        當(dāng)發(fā)現(xiàn)緩沖區(qū)已經(jīng)滿的時(shí)候,掛起生產(chǎn)者進(jìn)程
         */
        while (count == SIZE){
            wait();
        }

        data[in++] = item;
        count++;
        in %= SIZE;
        /*
        放入物品之后,通知消費(fèi)者緩沖區(qū)已經(jīng)有物品
         */
        notifyAll();
    }

    public synchronized int get() throws InterruptedException {

        /*
        當(dāng)發(fā)現(xiàn)緩沖區(qū)沒有物品時(shí),掛起消費(fèi)者進(jìn)程
         */
        while (count == 0){
            wait();
        }

        int item = data[out++];
        count--;
        out %= SIZE;

        // 取出數(shù)據(jù)之后,通知生產(chǎn)者緩沖區(qū)有空
        notifyAll();
        return item;
    }
}

讀者-寫者問(wèn)題

問(wèn)題描述

讀者-寫者問(wèn)題是另外一個(gè)經(jīng)典的同步問(wèn)題,問(wèn)題如下:有多個(gè)讀者以及至少一個(gè)寫者,多個(gè)讀者可以同時(shí)讀取文件,但是寫者與寫者、寫者與讀者之間必須進(jìn)行同步(很顯然的嘛,一旦出現(xiàn)了寫者,就必須進(jìn)行同步處理了)

偽代碼描述


var rmutex,wmutex:semaphore:=1,1
readcount int:=0

procedure write:
  begin
    repeat
      wait(wmutex);
      write
      signal(wmutex);
    until false;
  end

procedure read:
  begin
    repeat
      wait(rmutex);
        if(readcount == 0) then
          wait(wmutex);
        fi  
        readcount:= readcount + 1
      signal(rmutex);
      read

      wait(rmutex)
        readcount:=readcount - 1;
        if(readcount == 0) then
          signal(wmutex);
        fi
      signal(rmutex);
    until false;
  end
        

處理的方式非常靈活,使用readcount用于對(duì)讀者數(shù)量進(jìn)行計(jì)數(shù),如果是第一個(gè)讀者,則對(duì)wmutex進(jìn)行加鎖,防止此時(shí)寫者進(jìn)行操作,如果是最后一個(gè)讀者,則將wmutex進(jìn)行解鎖,表示此時(shí)已經(jīng)沒有任何讀者在進(jìn)行讀操作,寫者可以進(jìn)行寫操作,同時(shí),由于對(duì)readcount進(jìn)行操作本身必須進(jìn)行同步(多個(gè)讀者會(huì)對(duì)其進(jìn)行修改),所以必須對(duì)readcount進(jìn)行加鎖處理

具體實(shí)現(xiàn)


package cn.xuhuanfeng.cs;

import java.util.concurrent.Semaphore;

/**
 * Created by Huanfeng.Xu on 2017-06-19.
 * 讀者-寫者問(wèn)題的實(shí)現(xiàn)
 */
public class Reader_Writer {

    private int data;
    private final Semaphore W_MUTEX = new Semaphore(1);
    private final Semaphore R_MUTEX = new Semaphore(1);
    private int readerCount = 0;

    class Reader implements Runnable{

        @Override
        public void run() {

            while (true){

                try {
                    // 獲得更改readerCount的權(quán)限
                   R_MUTEX.acquire();
                   if (readerCount == 0){
                       // 對(duì)數(shù)據(jù)區(qū)進(jìn)行加鎖
                       W_MUTEX.acquire();
                   }
                   readerCount ++;
                   // 釋放對(duì)readerCount操作的權(quán)限
                   R_MUTEX.release();

                   System.out.printf("Data is : %d\n", data);

                   // 同上
                   R_MUTEX.acquire();
                   readerCount--;
                   if (readerCount == 0){
                       // 釋放數(shù)據(jù)區(qū)的鎖
                       W_MUTEX.release();
                   }
                   R_MUTEX.release();

                   Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    class Writer implements Runnable{

        @Override
        public void run() {
            int cnt = 0;
            while (true){
                try {
                    W_MUTEX.acquire();
                    data = ++cnt;
                    W_MUTEX.release();
                    System.out.println("--------------Update-----------------");
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

哲學(xué)家進(jìn)餐問(wèn)題

關(guān)于哲學(xué)家進(jìn)餐問(wèn)題的背景這里就不進(jìn)行介紹了

哲學(xué)家進(jìn)餐問(wèn)題基本的解決方案同上面,不過(guò)需要注意的是,需要保證哲學(xué)家們不會(huì)都拿同一個(gè)方向的筷子,所以可以讓編號(hào)是奇數(shù)的哲學(xué)家先拿左邊的筷子,再拿右邊的筷子,編號(hào)是偶數(shù)的哲學(xué)家,先拿右邊的筷子,再拿左邊的筷子,這樣可以有效地避免死鎖問(wèn)題,導(dǎo)致哲學(xué)家餓死。

進(jìn)程通信

進(jìn)程通信指的是進(jìn)程之間的信息交換

信號(hào)量作為通信機(jī)制的缺點(diǎn)

  • 效率低下
  • 通信對(duì)用戶不透明
  • 屬于一種低級(jí)通信

進(jìn)程通信的類型

  • 共享存儲(chǔ)器系統(tǒng)(無(wú)格式)
    • 基于共享數(shù)據(jù)結(jié)構(gòu)的通信(低效)
    • 基于共享存儲(chǔ)區(qū)的通信(高效)
  • 消息傳遞系統(tǒng)(有格式)
    • 直接通信:直接發(fā)送給用戶
    • 間接通信:將消息發(fā)送到"郵箱",然后用戶從郵箱中取出自己所要的消息
  • 管道通信(單向通信)

線程

引入線程的目的:減少程序并發(fā)執(zhí)行時(shí)所付出的時(shí)空開銷,使OS具有更好的并發(fā)性,原因在于,進(jìn)程在創(chuàng)建、調(diào)度、撤銷時(shí)的開銷大

線程與進(jìn)程的比較

  • 調(diào)度:線程作為調(diào)度和分派的基本單位,進(jìn)程作為擁有資源的基本單位
  • 并發(fā)性:進(jìn)程中的多個(gè)線程之間同樣可以并發(fā)執(zhí)行,并且同個(gè)進(jìn)程之間的線程進(jìn)行切換時(shí),不會(huì)引起進(jìn)程的切換
  • 擁有資源:進(jìn)程是系統(tǒng)中擁有資源的基本單位,線程一般不擁有系統(tǒng)資源,但是可以訪問(wèn)其隸屬的進(jìn)程的資源
  • 系統(tǒng)開銷:開銷更小,切換線程時(shí),不需要進(jìn)行過(guò)多的環(huán)境保存,撤銷時(shí),不需要進(jìn)行過(guò)多的資源回收

線程的屬性

在多線程os中,一個(gè)進(jìn)程通常包含多個(gè)線程,線程作為利用CPU的基本單位,是花費(fèi)最小的實(shí)體

  • 輕型實(shí)體:只含有必須的少量資源
  • 作為調(diào)度和分派的基本單位:切換速度快并且開銷小
  • 可并發(fā)執(zhí)行
  • 共享進(jìn)程資源:所有線程都具有相同的地址空間(進(jìn)程的地址空間)

線程的狀態(tài)

os中的每一個(gè)線程都可以用線程標(biāo)識(shí)符以及一組狀態(tài)參數(shù)進(jìn)行描述

  • 狀態(tài)參數(shù):
    • 寄存器狀態(tài)
    • 堆棧
    • 線程運(yùn)行狀態(tài)
      • 執(zhí)行狀態(tài)
      • 就緒狀態(tài)
      • 阻塞狀態(tài)
    • 優(yōu)先級(jí)
    • 線程專有存儲(chǔ)器
    • 信號(hào)屏蔽

線程的創(chuàng)建以及終止

程序啟動(dòng)時(shí),一般只有一個(gè)主線程,然后再由主線程根據(jù)需要啟動(dòng)其他線程

多線程os中的進(jìn)程

  • 作為系統(tǒng)資源分配的單位
  • 包含多個(gè)線程
  • 進(jìn)程不再是可執(zhí)行的實(shí)體

線程間的同步和通訊

  • 互斥鎖:用于實(shí)現(xiàn)線程間對(duì)資源互斥訪問(wèn)的機(jī)制
  • 條件變量:每個(gè)條件變量一般與一個(gè)互斥鎖一起使用
  • 信號(hào)量機(jī)制
    • 私用信號(hào)量
    • 公用信號(hào)量

線程的分類

  • 內(nèi)核支持線程:線程的處理均由內(nèi)核實(shí)現(xiàn),內(nèi)核為線程保留TCB,并且通過(guò)TCB感知線程
  • 用戶級(jí)線程:線程的信息處理不通過(guò)內(nèi)核,狀態(tài)保留在用戶空間中,內(nèi)核不能感知用戶級(jí)線程
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容