Nachos Lab3 同步机制
lab3 同步機制
任務完成情況
| Exercise1 | Y |
| Exercise2 | Y |
| Exercise3 | Y |
| Exercise4 | Y |
| *challenge1 | Y |
| *challenge2 | Y |
Exercise1 調研
調研Linux中實現的同步機制。
- Locking in the Linux Kernel
在include/linux路徑下:
互斥鎖
- mutex.h
其他鎖
- spinlock.h
- rwlock.h
- …
結論
Linux在內核中實現了很多種類不同的鎖,通常情況下用于系統軟件和硬件的管理。而對于用戶級進程,據我所知一般是使用ptherad庫。
Exercise2 源代碼閱讀
閱讀下列源代碼,理解Nachos現有的同步機制。
code/threads/synch.h和code/threads/synch.cc
code/threads/synchlist.h和code/threads/synchlist.cc
code/threads/synch.h(cc)
實現了信號量機制。
| int value | 信號量值,永遠大于等于0 |
| List *queue | 在P()中被阻塞的線程隊列,等待value>0之后被喚醒 |
| void P() | 當value == 0時,將currentThread放入queue中。掛起currentThread并執行其他線程;當value>0時,value– |
| void V() | 判斷queue中是否有元素,如果有,則喚醒,并將其加入就緒隊列;value++ |
Exercise3 實現鎖和條件變量
可以使用sleep和wakeup兩個原語操作(注意屏蔽系統中斷),也可以使用Semaphore作為唯一同步原語(不必自己編寫開關中斷的代碼)。
在開頭關中斷,在結尾開中斷,保證整個程序是原子操作。
Pthreads庫
pthreads提供了兩種同步機制:mutex和condition
-
POSIX Threads Programming
-
Mutex Variables
-
Condition Variables
-
Lock
Nachos已經有了一個Lock模板,我用semaphore來實現它。
我添加了兩個private變量:
class Lock {...private:...Thread *heldThread; //lab3 在isHeldByCurrentThread()使用Semaphore *semaphore; //信號量,在構造函數中將value初始化為1 };當currentThread獲得Lock的時候將heldThread指定為currentThread:
void Lock::Acquire() {IntStatus oldLevel = interrupt->SetLevel(IntOff);//關中斷semaphore->P();heldThread = currentThread;DEBUG('l', "%s has aquired %s", heldThread->getName(), name); //l means lockinterrupt->SetLevel(oldLevel); }當且僅當鎖的擁有者為currentTHread才可以釋放鎖。
更多的細節請查看code/thread/synch.cc
Condition
Nachos已經給了Condition的模板,我用Lock來實現它。
我添加了一個private成員變量queue作為阻塞隊列。
class Condition {private:List* queue; // 因某條件被阻塞的線程 };注意到所有的Condition成員函數都需要一個參數conditionlock,這是因為使用條件變量的線程必須在之前就已經獲得了鎖。
用sigenal來喚醒單個線程,broadcast來喚醒多個線程:
void Condition::Signal(Lock *conditionLock) {IntStatus oldLevel = interrupt->SetLevel(IntOff);//環境變量的所有者必須為當前線程ASSERT(conditionLock->isHeldByCurrentThread());//喚醒進程if (!queue->IsEmpty()){Thread *thread = (Thread *)queue->Remove();scheduler->ReadyToRun(thread);DEBUG('c', "%s wakes up \"%s\".\n", getName(), thread->getName());}interrupt->SetLevel(oldLevel); } void Condition::Broadcast(Lock *conditionLock) {IntStatus oldLevel = interrupt->SetLevel(IntOff);//環境變量的所有者必須為當前線程ASSERT(conditionLock->isHeldByCurrentThread());DEBUG('c', "broadcast : ");//喚醒所有進程while (!queue->IsEmpty()){Thread *thread = (Thread *)queue->Remove();scheduler->ReadyToRun(thread);DEBUG('c', "%s\t", thread->getName());}DEBUG('c', "\n");interrupt->SetLevel(oldLevel); }關于wait()的實現請查看code/thread/synch.cc
測試
我將在exercise中進行Lock和Condition的測試。
Exercise4 生產者消費者
基于Nachos中的信號量、鎖和條件變量,采用兩種方式實現同步和互斥機制應用(其中使用條件變量實現同步互斥機制為必選題目)。具體可選擇“生產者-消費者問題”、“讀者-寫者問題”、“哲學家就餐問題”、“睡眠理發師問題”等。(也可選擇其他經典的同步互斥問題)
這里我選擇實現生產者消費者問題,并使用Lock和Condition實現。代碼框架可以參考:
生產者消費者–wiki百科
實現
//---------------------------------------------------------------------- // Lab3 Exercise4 生產者消費者問題 // 在main中new一個生產者和一個消費者 // 消費者:每次從buffer中取一個元素 // 生產者:每次生產一個元素放入buffer // buff滿,生產者阻塞,buff空,消費者阻塞 // 保證生產者和消費者互斥訪問buffer //---------------------------------------------------------------------- #define BUFFER_SIZE 5 //buffer的大小 #define THREADNUM_P (Random() % 4 + 1) //生產者數,不超過4 #define THREADNUM_C (Random() % 4 + 1) //消費者數,不超過4 #define TESTTIME 500 //本次測試的總時間vector<char> buffer; //方便起見,用STL作為buffer Lock *mutex; //mutex->緩沖區的互斥訪問 Condition *full, *empty; //full->生產者的條件變量,empty->消費者的條件變量//消費者線程 void Comsumer(int dummy) {while (stats->totalTicks < TESTTIME) //約等于while(true),這樣寫可以在有限的時間內結束{//保證對緩沖區的互斥訪問mutex->Acquire();//緩沖區空,阻塞當前消費者while (!buffer.size()){printf("Thread \"%s\": Buffer is empty with size %d.\n", currentThread->getName(), buffer.size());empty->Wait(mutex);}//消費一個緩沖區物品ASSERT(buffer.size());buffer.pop_back();printf("Thread \"%s\" gets an item.\n", currentThread->getName());//若存在阻塞的生產者,將他們中的一個釋放if (buffer.size() == BUFFER_SIZE - 1)full->Signal(mutex);//釋放鎖mutex->Release();interrupt->OneTick(); //系統時間自增} }//生產者線程 void Producer(int dummy) {while (stats->totalTicks < TESTTIME) //約等于while(true),這樣寫可以在有限的時間內結束{//保證對緩沖區的互斥訪問mutex->Acquire();//緩沖區滿,阻塞當前線程,一定要使用while,如果用if,可能存在//這樣一種情況:生產者1判斷buffer滿,阻塞;當它再次上處理機時,//buffer還是滿的,但是它不會再判斷了,而是直接進入了臨界區while (buffer.size() == BUFFER_SIZE){printf("Thread \"%s\": Buffer is full with size %d.\n", currentThread->getName(), buffer.size());full->Wait(mutex);}//生產一個物品放入緩沖區ASSERT(buffer.size() < BUFFER_SIZE);buffer.push_back('0');printf("Thread \"%s\" puts an item.\n", currentThread->getName());//若存在阻塞的消費者,將他們中的一個釋放if (buffer.size() == 1)empty->Signal(mutex);//釋放鎖mutex->Release();interrupt->OneTick(); //系統時間自增} } void Lab3ProducerAndComsumer() {printf("Random created %d comsumers, %d producers.\n", THREADNUM_C, THREADNUM_P);full = new Condition("Full_condition"); //初始化fullempty = new Condition("Empty_condition"); //初始化emptymutex = new Lock("buffer_mutex"); //初始化mutexThread *threadComsumer[THREADNUM_C];Thread *threadProducer[THREADNUM_P];//初始化消費者for (int i = 0; i < THREADNUM_C; ++i){char threadName[20];sprintf(threadName, "Comsumer %d", i); //給線程命名threadComsumer[i] = new Thread(strdup(threadName));threadComsumer[i]->Fork(Comsumer, 0);}//初始化生產者for (int i = 0; i < THREADNUM_P; ++i){char threadName[20];sprintf(threadName, "Producer %d", i); //給線程命名threadProducer[i] = new Thread(strdup(threadName));threadProducer[i]->Fork(Producer, 0);}// scheduler->Print();while (!scheduler->isEmpty())currentThread->Yield(); //跳過main的執行//結束printf("Producer consumer test Finished.\n"); }測試
本次試驗采用隨機時間片模擬真實場景,在terminal中輸入./nachos -d c -rs -q 6可查看結果:
-d c means condition debug, -rs means random seed
vagrant@precise32:/vagrant/nachos/nachos-3.4/code/threads$ ./nachos -d c -rs -q 6 Random created 2 comsumers, 3 producers. Thread "Comsumer 0": Buffer is empty with size 0. Empty_condition has blocked thread "Comsumer 0". Thread "Comsumer 1": Buffer is empty with size 0. Empty_condition has blocked thread "Comsumer 1". Thread "Producer 0" puts an item. Empty_condition wakes up "Comsumer 0". Thread "Producer 0" puts an item. ======Random context switch, Ticks = 190===== Thread "Producer 1" puts an item. Thread "Producer 1" puts an item. ======Random context switch, Ticks = 250===== Thread "Producer 2" puts an item. Thread "Producer 2": Buffer is full with size 5. Full_condition has blocked thread "Producer 2". Thread "Producer 3": Buffer is full with size 5. Full_condition has blocked thread "Producer 3". Thread "Comsumer 0" gets an item. Full_condition wakes up "Producer 2". Thread "Comsumer 0" gets an item. Thread "Comsumer 0" gets an item. ======Random context switch, Ticks = 420===== Thread "Producer 0" puts an item. Thread "Producer 0" puts an item. Thread "Producer 0" puts an item. ======Random context switch, Ticks = 550===== Thread "Producer 2": Buffer is full with size 5. Full_condition has blocked thread "Producer 2". Producer consumer test Finished. No threads ready or runnable, and no pending interrupts. Assuming the program completed. Machine halting!Ticks: total 691, idle 101, system 590, user 0 Disk I/O: reads 0, writes 0 Console I/O: reads 0, writes 0 Paging: faults 0 Network I/O: packets received 0, sent 0Cleaning up...結論
結果顯示,成功使用semaphore和condition解決生產者消費者問題。
*challenge1 Barrier
可以使用Nachos 提供的同步互斥機制(如條件變量)來實現barrier,使得當且僅當若干個線程同時到達某一點時方可繼續執行。
背景知識
- Wiki - Barrier (computer science)
- Latches And Barriers
我仿造了std::barrier的arrive_and_wait的實現,并在code/thread/synch.h中添加了Barrier類:
class Barrier { public:Barrier(char *debugName, int num); // 構造函數~Barrier(); // 析構函數char *getName() { return (name); } // 調試用void stopAndWait(); // 在所有線程到達之前阻塞當前線程private:char *name; // 調試用int remain; // 還剩多少線程沒到?int threadNum; // 線程總數Lock *mutex; // condition中使用的鎖Condition *condition; // 用來阻塞線程并喚醒他們 };具體的實現請查看code/thread/synch.cc
在code/thread/threadtest.cc中編寫了Lab3Barrier()函數,testnum = 5:
//---------------------------------------------------------------------- // lab3 challenge1 barrier // 在main中new 4 個線程,四個線程分別對4個全局變量進行賦值 // 共分三個階段,每個階段賦值不同,但是在相同的階段中, // 每個線程對對應元素賦值是相同的,本程序可用于barrier測試 //----------------------------------------------------------------------#define THREADNUM 4//線程數 #define PHASENUM 3//測試的階段數 int num[THREADNUM];//4個全局變量 Barrier *barrier;預期結果:每個階段中,數組num中的每個元素相等。
測試
在terminal中輸入./nachos -d b -q 5可查看結果:
-d b means barrier debug
vagrant@precise32:/vagrant/nachos/nachos-3.4/code/threads$ ./nachos -d b -q 5 Phase 1: thread "Barrier test 0" finished assignment, num[0] = 1. Thread "Barrier test 0" reached barrier with remain = 3. Phase 1: thread "Barrier test 1" finished assignment, num[1] = 1. Thread "Barrier test 1" reached barrier with remain = 2. Phase 1: thread "Barrier test 2" finished assignment, num[2] = 1. Thread "Barrier test 2" reached barrier with remain = 1. Phase 1: thread "Barrier test 3" finished assignment, num[3] = 1. Thread "Barrier test 3" reached barrier with remain = 0. All threads reached barrier. Phase 2: thread "Barrier test 3" finished assignment, num[3] = 2. Thread "Barrier test 3" reached barrier with remain = 3. Phase 2: thread "Barrier test 0" finished assignment, num[0] = 2. Thread "Barrier test 0" reached barrier with remain = 2. Phase 2: thread "Barrier test 1" finished assignment, num[1] = 2. Thread "Barrier test 1" reached barrier with remain = 1. Phase 2: thread "Barrier test 2" finished assignment, num[2] = 2. Thread "Barrier test 2" reached barrier with remain = 0. All threads reached barrier. Phase 3: thread "Barrier test 2" finished assignment, num[2] = 3. Thread "Barrier test 2" reached barrier with remain = 3. Phase 3: thread "Barrier test 3" finished assignment, num[3] = 3. Thread "Barrier test 3" reached barrier with remain = 2. Phase 3: thread "Barrier test 0" finished assignment, num[0] = 3. Thread "Barrier test 0" reached barrier with remain = 1. Phase 3: thread "Barrier test 1" finished assignment, num[1] = 3. Thread "Barrier test 1" reached barrier with remain = 0. All threads reached barrier. Barrier test Finished. No threads ready or runnable, and no pending interrupts. Assuming the program completed. Machine halting!Ticks: total 320, idle 0, system 320, user 0 Disk I/O: reads 0, writes 0 Console I/O: reads 0, writes 0 Paging: faults 0 Network I/O: packets received 0, sent 0Cleaning up...結果顯示,共進行了三個階段的賦值,每個階段中,每個線程正確地對其負責的變量進行了賦值;在不同的階段中,每個線程的賦值不同,符合預期,實驗成功。為了測試在隨機時間片下程序是否具有正確性,輸入-rs 查看隨機時間片下的結果:
vagrant@precise32:/vagrant/nachos/nachos-3.4/code/threads$ make;./nachos -d c -rs -q 5 make: `nachos' is up to date. Phase 1: thread "Barrier test 0" finished assignment, num[0] = 1. Barrier condition has blocked thread "Barrier test 0". Phase 1: thread "Barrier test 1" finished assignment, num[1] = 1. Barrier condition has blocked thread "Barrier test 1". Phase 1: thread "Barrier test 2" finished assignment, num[2] = 1. ===============Random context switch, Ticks = 190=============== Phase 1: thread "Barrier test 3" finished assignment, num[3] = 1. Barrier condition has blocked thread "Barrier test 3". broadcast : Barrier test 0 Barrier test 1 Barrier test 3 ===============Random context switch, Ticks = 280=============== Phase 2: thread "Barrier test 2" finished assignment, num[2] = 2. Barrier condition has blocked thread "Barrier test 2". Phase 2: thread "Barrier test 0" finished assignment, num[0] = 2. Barrier condition has blocked thread "Barrier test 0". Phase 2: thread "Barrier test 1" finished assignment, num[1] = 2. Barrier condition has blocked thread "Barrier test 1". ===============Random context switch, Ticks = 460=============== Phase 2: thread "Barrier test 3" finished assignment, num[3] = 2. broadcast : Barrier test 2 Barrier test 0 Barrier test 1 Phase 3: thread "Barrier test 3" finished assignment, num[3] = 3. ===============Random context switch, Ticks = 580=============== Phase 3: thread "Barrier test 2" finished assignment, num[2] = 3. Barrier condition has blocked thread "Barrier test 2". Barrier condition has blocked thread "Barrier test 3". Phase 3: thread "Barrier test 0" finished assignment, num[0] = 3. Barrier condition has blocked thread "Barrier test 0". Phase 3: thread "Barrier test 1" finished assignment, num[1] = 3. broadcast : Barrier test 2 Barrier test 3 Barrier test 0 ===============Random context switch, Ticks = 780=============== Barrier test Finished. No threads ready or runnable, and no pending interrupts. Assuming the program completed. Machine halting!Ticks: total 916, idle 56, system 860, user 0 Disk I/O: reads 0, writes 0 Console I/O: reads 0, writes 0 Paging: faults 0 Network I/O: packets received 0, sent 0Cleaning up...結論
在隨機時間片下結果依然正確,我們的Barrier實現成功!
*Challenge2 實現read/write lock
基于Nachos提供的lock(synch.h和synch.cc),實現read/write lock。使得若干線程可以同時讀取某共享數據區內的數據,但是在某一特定的時刻,只有一個線程可以向該共享數據區寫入數據。
讀者寫者問題分為兩類:
兩類問題都可能導致饑餓,其中第一類會導致寫者饑餓,第二類會導致讀者饑餓。
本次實驗將實現第二類讀寫鎖。
Readers–writer lock - WIKIPEDIA)
使用Condition和Lock
可以用一個條件變量,COND,一個普通的(互斥)鎖,g,和各種計數器和標志描述當前處于活動狀態或等待的線程。對于寫優先的RW鎖,可以使用兩個整數計數器和一個布爾標志:
- num_readers_active:已獲取鎖的讀者的數量(整數)
- num_writers_waiting:等待訪問的寫者數(整數)
- writer_active:寫者是否已獲得鎖(布爾值)
最初num_readers_active和num_writers_waiting為零,而writer_active為false。
我將讀寫鎖封裝成一個類code/threads/synch.h:
class RWLock { public:RWLock(char *debugName); // 構造函數~RWLock(); // 析構函數char *getName() { return (name); } // debug輔助// 讀者鎖void ReaderAcquire();void ReaderRelease();// 寫者鎖void WriterAcquire();void WriterRelease();private:char *name; // debug用int num_readers_active; //已獲取鎖的讀者的數量int num_writers_waiting; //等待訪問的寫者數(整數)int writer_active; //寫者是否已獲得鎖(布爾值)Condition *COND; //條件變量CONDLock *g; //互斥鎖g };其他瑣碎的代碼請查看code/threads/synch.cc
測試
在code/threads/threatest.cc中編寫了Lab3RWLock()函數,testnum = 7:
//---------------------------------------------------------------------- // lab3 Challenge2 RWLock // 隨機產生一定數量的讀者和寫者對臨界資源buffer // 進行讀寫; 寫者的任務:寫一句拿破侖的名言: // "Victory belongs to the most persevering" // 構造兩個寫者,第一個負責寫前半部分,第二個負責寫 // 后半部分,每個寫者寫一個字符就切換,觀察是否會被 // 其他讀者或者寫者搶占使用權,如果不會,證明寫者優 // 先實現成功 //---------------------------------------------------------------------- #define THREADNUM_R (Random() % 4 + 1) //讀者數,不超過4 #define THREADNUM_W 2 //寫者數 const string QUOTE = "Victory belongs to the most persevering."; //拿破侖的名言 const int QUOTE_SIZE = QUOTE.size(); //長度 int shared_i = 0; //寫者公用,用于定位,初始化為零 RWLock *rwlock; //讀寫鎖 string RWBuffer; //buffer//寫者線程 void Writer(int writeSize) {while (shared_i < writeSize){rwlock->WriterAcquire();RWBuffer.push_back(QUOTE[shared_i++]);printf("%s is writing: %s\n", currentThread->getName(), RWBuffer.c_str());rwlock->WriterRelease();} }//讀者線程 void Reader(int dummy) {while (shared_i < QUOTE_SIZE){rwlock->ReaderAcquire();printf("%s is reading :%s\n", currentThread->getName(), RWBuffer.c_str());rwlock->ReaderRelease();} }void Lab3RWLock() {printf("Random created %d readers, %d writers.\n", THREADNUM_R, THREADNUM_W);rwlock = new RWLock("RWLock"); //初始化rwlockThread *threadReader[THREADNUM_R];Thread *threadWriter[THREADNUM_W];//初始化讀者for (int i = 0; i < THREADNUM_R; ++i){char threadName[20];sprintf(threadName, "Reader %d", i); //給線程命名threadReader[i] = new Thread(strdup(threadName));threadReader[i]->Fork(Reader, 0);}//初始化寫者for (int i = 0; i < THREADNUM_W; ++i){char threadName[20];sprintf(threadName, "Writer %d", i); //給線程命名threadWriter[i] = new Thread(strdup(threadName));int val = !i ? QUOTE_SIZE - 20 : QUOTE_SIZE;threadWriter[i]->Fork(Writer, val);}while (!scheduler->isEmpty())currentThread->Yield(); //跳過main的執行//結束printf("Secondary Reader Writer test Finished.\n"); }在terminal中輸入./nachos -q 7可查看結果:
vagrant@precise32:/vagrant/nachos/nachos-3.4/code/threads$ make;./nachos -q 7 make: `nachos' is up to date. Random created 2 readers, 2 writers. Writer 0 is writing: V Writer 0 is writing: Vi Writer 0 is writing: Vic Writer 0 is writing: Vict Writer 0 is writing: Victo Writer 0 is writing: Victor Writer 0 is writing: Victory Writer 0 is writing: Victory Writer 0 is writing: Victory b Writer 0 is writing: Victory be Writer 0 is writing: Victory bel Writer 0 is writing: Victory belo Writer 0 is writing: Victory belon Writer 0 is writing: Victory belong Writer 0 is writing: Victory belongs Writer 0 is writing: Victory belongs Writer 0 is writing: Victory belongs t Writer 0 is writing: Victory belongs to Writer 0 is writing: Victory belongs to Writer 0 is writing: Victory belongs to t Writer 1 is writing: Victory belongs to th Writer 1 is writing: Victory belongs to the Writer 1 is writing: Victory belongs to the Writer 1 is writing: Victory belongs to the m Writer 1 is writing: Victory belongs to the mo Writer 1 is writing: Victory belongs to the mos Writer 1 is writing: Victory belongs to the most Writer 1 is writing: Victory belongs to the most Writer 1 is writing: Victory belongs to the most p Writer 1 is writing: Victory belongs to the most pe Writer 1 is writing: Victory belongs to the most per Writer 1 is writing: Victory belongs to the most pers Writer 1 is writing: Victory belongs to the most perse Writer 1 is writing: Victory belongs to the most persev Writer 1 is writing: Victory belongs to the most perseve Writer 1 is writing: Victory belongs to the most persever Writer 1 is writing: Victory belongs to the most perseveri Writer 1 is writing: Victory belongs to the most perseverin Writer 1 is writing: Victory belongs to the most persevering Writer 1 is writing: Victory belongs to the most persevering. Reader 0 is reading :Victory belongs to the most persevering. Reader 1 is reading :Victory belongs to the most persevering. Secondary Reader Writer test Finished. No threads ready or runnable, and no pending interrupts. Assuming the program completed. Machine halting!Ticks: total 1760, idle 0, system 1760, user 0 Disk I/O: reads 0, writes 0 Console I/O: reads 0, writes 0 Paging: faults 0 Network I/O: packets received 0, sent 0Cleaning up...輸入./nachos -d c -q 7可以查看線程阻塞信息:
vagrant@precise32:/vagrant/nachos/nachos-3.4/code/threads$ make;./nachos -d c -q 7 make: `nachos' is up to date. Random created 2 readers, 2 writers. Writer 0 is writing: V Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Vi Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Vic Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Vict Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Victo Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Victor Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Victory Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Victory Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Victory b Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Victory be Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Victory bel Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Victory belo Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Victory belon Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Victory belong Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Victory belongs Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Victory belongs Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Victory belongs t Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Victory belongs to Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Victory belongs to Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 0 is writing: Victory belongs to t Condition has blocked thread "Writer 1". Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Writer 1 Reader 0 Reader 1 Writer 1 is writing: Victory belongs to th Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the m Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the mo Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the mos Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the most Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the most Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the most p Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the most pe Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the most per Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the most pers Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the most perse Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the most persev Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the most perseve Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the most persever Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the most perseveri Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the most perseverin Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the most persevering Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Writer 1 is writing: Victory belongs to the most persevering. Condition has blocked thread "Reader 0". Condition has blocked thread "Reader 1". broadcast : Reader 0 Reader 1 Reader 0 is reading :Victory belongs to the most persevering. broadcast : Reader 1 is reading :Victory belongs to the most persevering. broadcast : Secondary Reader Writer test Finished. No threads ready or runnable, and no pending interrupts. Assuming the program completed. Machine halting!Ticks: total 1760, idle 0, system 1760, user 0 Disk I/O: reads 0, writes 0 Console I/O: reads 0, writes 0 Paging: faults 0 Network I/O: packets received 0, sent 0Cleaning up...結論
結果顯示,在寫者寫完之前,讀者和其它寫者會被一直阻塞,直到寫者完成自己的任務之后,其它寫者才能進行寫,沒有寫者寫了,讀者才能進行讀,并且多個讀者之間可以并發讀,這表明我們的RWLock實現成功。
challenge 3 研究Linux的kfifo機制是否可以移植到Nachos上作為一個新的同步模塊
todo
總結
以上是生活随笔為你收集整理的Nachos Lab3 同步机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: yarn 安装 sass
- 下一篇: 简单实现顶部固定,中部自适应布局