程序和執行緒(一)

2022-05-03 21:33:10 字數 4280 閱讀 5666

1.程序是在系統中能獨立執行並作為資源分配的基本單位。

tips:並行是指在同一時刻多個事件一起執行,併發是指在同一時間間隔中多個事件一起執行。

2.程序控制塊(process control block,pcb):用於描述程序的基本資訊和執行狀況。

程序的特性:

3.程序的基本狀態

tips:只有就緒狀態和執行狀態可以互相轉換。

後兩個狀態不一定加。

1.執行緒是獨立排程的基本單位。

2.執行緒狀態與程序3大狀態一樣,包括轉換。

1.排程

2.擁有資源

ps:如果執行緒也可以擁有資源,那麼執行緒切換的開銷也就很大了,引入執行緒就沒有太大的意義了。

3.系統開銷

4.通訊方式

1.核心級執行緒(kernel level threads)

2.使用者級執行緒(user level threads)

3.組合方式的實現(多執行緒模型)

一對一模型:每個使用者執行緒對映到乙個核心級執行緒上。

多對多模型(m>=n):將m個使用者級執行緒對映到n個核心級執行緒上。

程序排程又稱低階排程,主要任務是按照某種方法和策略從就緒佇列中選擇乙個程序分配處理機

程序排程方式可以分為:

1.先來先服務(first come first serverd,fcfs)排程演算法

2.短作業優先(short job first,sjf)排程演算法

3.最短剩餘時間優先(short remaining time next,srtf)排程演算法

4.高響應比優先排程演算法

5.時間片輪轉排程演算法

6.優先順序排程演算法

按可否改變可以分成:

7.多級反饋佇列

多道程式的情況下程序是併發執行的,為了協調程序間制約關係,引入程序同步概念。比如1+2*3,分為加法程序和乘法程序,如果不進行協調就可能發生加法發生在乘法之前。

1.臨界資源

2.同步

3.互斥

4.訊號量

訊號量是乙個整型變數,可以進行wait(),signal()操作(p,v或者down,up)操作。

如果訊號量只能取0,1那麼就是互斥量,0表示臨界區加鎖,1表示臨界區解鎖。

typedef int semaphore;

semaphore mutex = 1;

void p1()

void p2()

5.管程

使用訊號量訪問資源的時候要進行同步操作,大量的同步操作就被分散在各個程序中,而且可能因為同步程序使用不當造成死鎖,於是使用管程將控制管理的**獨立出來,不僅不容易出錯,也更容易管理了。

管程:由一組資料以及定義在這組資料上的操作組成的一種軟體模組,這組操作能夠初始化管程中的資料和同步程序。

管程引入了條件變數以及相關的操作:wait()signal()來實現同步操作。對條件變數執行 wait() 操作會導致呼叫程序阻塞,把管程讓出來給另乙個程序持有。signal() 操作用於喚醒被阻塞的程序。

// 管程

monitor producerconsumer

condition full, empty;

integer count := 0;

condition c;

procedure insert(item: integer);

begin

if count = n then wait(full);

insert_item(item);

count := count + 1;

if count = 1 then signal(empty);

end;

function remove: integer;

begin

if count = 0 then wait(empty);

remove = remove_item;

count := count - 1;

if count = n -1 then signal(full);

end;

end monitor;

// 生產者客戶端

procedure producer

begin

while true do

begin

item = produce_item;

producerconsumer.insert(item);

endend;

// 消費者客戶端

procedure consumer

begin

while true do

begin

item = producerconsumer.remove;

consume_item(item);

endend;

1.生產者消費者問題

生產者消費者問題

問題描述:使用乙個緩衝區來儲存物品,只有緩衝區沒有滿,生產者才可以放入物品;只有緩衝區不為空,消費者才可以拿走物品。

因為緩衝區屬於臨界資源,因此需要使用乙個互斥量 mutex 來控制對緩衝區的互斥訪問。

為了同步生產者和消費者的行為,需要記錄緩衝區中物品的 數量。數量可以使用訊號量來進行統計,這裡需要使用兩個訊號量:empty 記錄空緩衝區的數量,full 記錄滿緩衝區的數量。其中,empty 訊號量是在生產者程序中使用,當 empty 不為 0 時,生產者才可以放入物品;full 訊號量是在消費者程序中使用,當 full 訊號量不為 0 時,消費者才可以取走物品。

注意,不能先對緩衝區進行加鎖,再測試訊號量。也就是說,不能先執行 down(mutex) 再執行 down(empty)。如果這麼做了,那麼可能會出現這種情況:生產者對緩衝區加鎖後,執行 down(empty) 操作,發現 empty = 0,此時生產者睡眠。消費者不能進入臨界區,因為生產者對緩衝區加鎖了,消費者就無法執行 up(empty) 操作,empty 永遠都為 0,導致生產者永遠等待下,不會釋放鎖,消費者因此也會永遠等待下去。

#define n 100

typedef int semaphore;

semaphore mutex = 1;

semaphore empty = n;

semaphore full = 0;

void producer()

}void consumer()

}

2.讀者寫者問題

允許多個讀者同時讀檔案

只允許乙個寫者往檔案中寫入

寫者在寫入的時候禁止讀者和寫者操作

int count=0; //計數器

semaphore mutex=1; //計數器互斥量

semaphore rw=1; //讀寫互斥量

writer()

}reader()

}

3.哲學家問題

五個哲學家坐在桌子上,兩人之間有乙個筷子,要同時擁有兩個筷子才能進餐,那麼就有可能造成飢餓或者死鎖。

解決辦法:

#define n 5

#define left (i + n - 1) % n // 左鄰居

#define right (i + 1) % n // 右鄰居

#define thinking 0

#define hungry 1

#define eating 2

typedef int semaphore;

int state[n]; // 跟蹤每個哲學家的狀態

semaphore mutex = 1; // 臨界區的互斥,臨界區是 state 陣列,對其修改需要互斥

semaphore s[n]; // 每個哲學家乙個訊號量

void philosopher(int i)

}void take_two(int i)

void put_two(i)

void eat(int i)

// 檢查兩個鄰居是否都沒有用餐,如果是的話,就 up(&s[i]),使得 down(&s[i]) 能夠得到通知並繼續執行

void check(i)

}

執行緒和程序

標準的定義是 程序是執行緒的容器,乙個程序可於乙個或者多個執行緒,它是系統分配資源的基本單位 同乙個程序下,執行緒共享位址空降 已經開啟的檔案 訊號處理函式 報警訊號和其他,執行緒自己只保留程式計數器和棧。但是很遺憾的,這個只是教科書上的定義,實際情況是每個作業系統實現的作業系統特性不同,實現的方法...

程序和執行緒

乙個程序就是當前正在執行的乙個程式,包括程式的暫存器 程式計數器和變數的當前值。不同的程序擁有不同的位址空間。而執行緒可以理解為是程序中的控制流。同乙個程序內也就是說在同乙個位址空間內可以有多個控制流。也就是可以有多個線 程,他們共享位址空間。我們通常將程序視為是資源的集合,程序中有程式的正文 資料...

執行緒和程序

對於求職者,在面試的時候大多都會被問到 你對多執行緒了解麼?給我講講執行緒和程序的區別吧。在unix中,乙個程序可以理解為執行緒 位址空間 檔案描述符 資料,道破現實,其實就相當於老闆和員工,老闆就是程序,員工就是執行緒。老闆需要僱傭若干員工 執行緒 還要有辦公樓 位址空間 還要有若干的辦公裝置 檔...