日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > windows >内容正文

windows

我是如何学习写一个操作系统(七):进程的同步与信号量

發(fā)布時(shí)間:2023/12/20 windows 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 我是如何学习写一个操作系统(七):进程的同步与信号量 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

在多進(jìn)程的運(yùn)行環(huán)境下,進(jìn)程是并發(fā)執(zhí)行的,不同進(jìn)程間存在著不同的相互制約關(guān)系。為了協(xié)調(diào)進(jìn)程之間的相互制約關(guān)系,達(dá)到資源共享和進(jìn)程協(xié)作,避免進(jìn)程之間的沖突,引入了進(jìn)程同步的概念。

臨界資源

多個(gè)進(jìn)程可以共享系統(tǒng)中的各種資源,但其中許多資源一次只能為一個(gè)進(jìn)程所使用,我們把一次只允許一個(gè)進(jìn)程使用的資源成為臨界資源。
對(duì)臨界資源的訪問(wèn),必須互斥的進(jìn)行。每個(gè)進(jìn)程中,訪問(wèn)臨界資源的那段代碼成為臨界區(qū)。

為了保證臨界資源的正確使用,可以把臨界資源的訪問(wèn)過(guò)程分為四個(gè)部分。

  • 進(jìn)入?yún)^(qū)。為了進(jìn)入臨界區(qū)使用臨界資源,在進(jìn)入去要檢查可否進(jìn)入臨界區(qū)。
  • 臨界區(qū)。進(jìn)程中訪問(wèn)臨界資源的那段代碼。
  • 退出區(qū)。將正在訪問(wèn)臨界區(qū)的標(biāo)志清除。
  • 剩余區(qū)。代碼中的其余部分。

一般實(shí)現(xiàn)進(jìn)程的同步有這幾種方法:

  • 提過(guò)硬件提供的實(shí)現(xiàn)
  • 信號(hào)量
  • 管程

生產(chǎn)者-消費(fèi)者實(shí)例

下面的代碼就分別是生產(chǎn)者進(jìn)程和消費(fèi)者進(jìn)程,而buffer就是臨界資源

  • 當(dāng)生產(chǎn)者要訪問(wèn)臨界資源時(shí),會(huì)先判斷buffer是不是已經(jīng)滿(mǎn)了,而消費(fèi)者則判斷buffer是不是空的,這就是訪問(wèn)臨界資源的進(jìn)入?yún)^(qū)

  • 而中間對(duì)buffer的操作就是臨界區(qū)

  • 最后對(duì)counter的加減就是設(shè)置對(duì)臨界區(qū)訪問(wèn)的標(biāo)志

  • 但是這里依舊也有可能出現(xiàn)問(wèn)題,比如當(dāng)進(jìn)程走到in = (in + 1) % BUFFER_SIZE;的時(shí)候,這時(shí)候操作系統(tǒng)進(jìn)行調(diào)度,這時(shí)候的counter的值可能還是0,所以消費(fèi)者進(jìn)程可能就會(huì)出現(xiàn)問(wèn)題

這里的處理可以是利用關(guān)閉中斷來(lái)限制進(jìn)程的切換,但是在多核CPU下一樣不管用

這里就涉及到了臨界區(qū)的保護(hù)了

#define BUFFER_SIZE 10 typedef struct { . . . } item; item buffer[BUFFER_SIZE]; int in = out = counter = 0 while (true) {while(counter== BUFFER_SIZE); buffer[in] = item;in = (in + 1) % BUFFER_SIZE;counter++; } while (true) {while(counter== 0) ; item = buffer[out];out = (out + 1) % BUFFER_SIZE;counter--; }

信號(hào)量

什么是信號(hào)量

為了防止出現(xiàn)因多個(gè)程序同時(shí)訪問(wèn)一個(gè)共享資源而引發(fā)的一系列問(wèn)題,我們需要一種方法,它可以通過(guò)生成并使用令牌來(lái)授權(quán),在任一時(shí)刻只能有一個(gè)執(zhí)行線(xiàn)程訪問(wèn)代碼的臨界區(qū)。

為了避免像上面一樣會(huì)發(fā)生競(jìng)爭(zhēng)條件,程序?qū)π盘?hào)量訪問(wèn)都是原子操作,且只允許對(duì)它進(jìn)行等待(即P(信號(hào)變量))和發(fā)送(即V(信號(hào)變量))信息操作。

信號(hào)量的工作原理

由于信號(hào)量只能進(jìn)行兩種操作等待和發(fā)送信號(hào),即P(sv)和V(sv),他們的行為是這樣的:

  • P(sv):如果sv的值大于零,就給它減1;如果它的值為零,就掛起該進(jìn)程的執(zhí)行
  • V(sv):如果有其他進(jìn)程因等待sv而被掛起,就讓它恢復(fù)運(yùn)行,如果沒(méi)有進(jìn)程因等待sv而掛起,就給它加1.

舉個(gè)例子,就是兩個(gè)進(jìn)程共享信號(hào)量sv,一旦其中一個(gè)進(jìn)程執(zhí)行了P(sv)操作,它將得到信號(hào)量,并可以進(jìn)入臨界區(qū),使sv減1。而第二個(gè)進(jìn)程將被阻止進(jìn)入臨界區(qū),因?yàn)楫?dāng)它試圖執(zhí)行P(sv)時(shí),sv為0,它會(huì)被掛起以等待第一個(gè)進(jìn)程離開(kāi)臨界區(qū)域并執(zhí)行V(sv)釋放信號(hào)量,這時(shí)第二個(gè)進(jìn)程就可以恢復(fù)執(zhí)行。

Linux 0.11的進(jìn)程同步

在Linux 0.11里是沒(méi)有實(shí)現(xiàn)信號(hào)量的,考慮后面會(huì)自己實(shí)現(xiàn)一個(gè)。這里先看一下Linux 0.11里用來(lái)進(jìn)行進(jìn)程同步的兩個(gè)函數(shù)

sleep_on

  • p實(shí)際上指的是一個(gè)等待隊(duì)列

  • 如果當(dāng)前進(jìn)程是進(jìn)程0或者無(wú)效,就直接退出

  • 然后把要等待的進(jìn)程放到等待隊(duì)列的頭節(jié)點(diǎn),把狀態(tài)設(shè)置為不可中斷的等待狀態(tài)

    這里隊(duì)列的形成非常非常的隱蔽,首先把用tmp指向之前的進(jìn)程,在把當(dāng)前要睡眠的進(jìn)程放入,而之所以能形成隊(duì)列,是因?yàn)楝F(xiàn)在放入隊(duì)列的進(jìn)程的tmp作為局部變量是保存在這個(gè)進(jìn)程的堆棧中的,這樣在把進(jìn)程切換回來(lái)的時(shí)候,tmp就自然的指向上一個(gè)進(jìn)程了。

  • 最后當(dāng)這個(gè)進(jìn)程被喚醒的時(shí)候,會(huì)回到if語(yǔ)句喚醒等待隊(duì)列中所有進(jìn)程

void sleep_on(struct task_struct **p) {struct task_struct *tmp;if (!p)return;if (current == &(init_task.task))panic("task[0] trying to sleep");tmp = *p;*p = current;current->state = TASK_UNINTERRUPTIBLE;schedule();if (tmp)tmp->state=0; }

wake_up

  • 喚醒 p 指向的任務(wù)。 p是任務(wù)等待隊(duì)列頭指針。由于新等待任務(wù)是插入在等待隊(duì)列頭指針處的,
void wake_up(struct task_struct **p) {if (p && *p) {(**p).state=0; // 置為就緒(可運(yùn)行)狀態(tài)TASK_RUNNING.*p=NULL;} }

小結(jié)

首先竟然有了多進(jìn)程,那在訪問(wèn)共享資源的時(shí)候自然就會(huì)發(fā)生制約關(guān)系,所以才引入了進(jìn)程同步的概念。

而進(jìn)程同步的關(guān)鍵就是對(duì)臨界區(qū)的保護(hù),信號(hào)量就是一種可以很好的實(shí)現(xiàn)對(duì)臨界區(qū)保護(hù)的方法

轉(zhuǎn)載于:https://www.cnblogs.com/secoding/p/11428751.html

總結(jié)

以上是生活随笔為你收集整理的我是如何学习写一个操作系统(七):进程的同步与信号量的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。