PV操作


PV操作:

P操作:passeren,通過,理解為申請資源

V操作:vrijgeven,釋放,理解為釋放資源

 

 

 

P操作定義如下:

1.sem減1。

2.若sem>=0,則P操作返回,該線程可以”通過“並繼續執行。 

3.若sem<0,則該線程被阻塞,進入操作系統的阻塞隊列。

 

 

V操作定義如下:

1.sem加1。

2.若sem>0,則V操作返回,該線程繼續執行。

3.若sem<=0,則從阻塞隊列中喚醒一個阻塞在該信號量上的線程,然后再返回原線程(調用V操作的線程)繼續執行。

 

 

多線程經典案例:

生產者消費者問題

include<windows.h> #include<queue> #include<process.h>
using namespace std; //用EVENT解決生產者消費者問題 //有一個倉庫
queue<int>store; int StoreSize = 3;//倉庫可以放3個貨物
int ID = 1;//貨物起始ID //定義一個隨機數組,模擬隨即生產速度
int arr1[10] = { 2,1,4,0,3,4,6,1,9,0 }; int arr2[10] = { 1,1,4,8,3,5,6,1,2,0 }; HANDLE hEvent1 = INVALID_HANDLE_VALUE;//有貨物時通知消費者取貨
HANDLE hEvent2 = INVALID_HANDLE_VALUE;//倉庫為空位時通知生產者開始生產 //生產者
void ProducerThread(LPVOID param); //消費者
void ConsumerThread(LPVOID param); int main() { hEvent1 = CreateEvent(NULL, TRUE, TRUE, L"事件對象1");//需要先開始生產
    hEvent2 = CreateEvent(NULL, TRUE, FALSE, L"事件對象2");//一開始倉庫是空的沒貨取
 uintptr_t t1 =_beginthread(ProducerThread,0,NULL); uintptr_t t2= _beginthread(ConsumerThread, 0, NULL); //無限等待兩個線程運行結束
    HANDLE hArr[] = { (HANDLE)t1 ,(HANDLE)t2 }; WaitForMultipleObjects(2, hArr, TRUE, INFINITE); CloseHandle(hEvent1); CloseHandle(hEvent2); return 0; } //生產者
void ProducerThread(LPVOID param) { while (TRUE) { //看Event是否允許生產,不允許無限等待
 WaitForSingleObject(hEvent1,INFINITE); if (store.size() < StoreSize)//有空位才生產
 { int id = ID++;//貨物ID號
            printf("生產產品:%d\n",id); store.push(id);//把貨物放到倉庫中
            Sleep(arr1[id%10]*1000);//生產速度不確定
 } else //倉庫滿了,需要停止生產
 { ResetEvent(hEvent1); printf("倉庫已滿!\n"); } //倉庫有貨物,可以通知消費者取貨
        if (store.size() > 0) { SetEvent(hEvent2);//讓消費者的事件對象為有信號
 } } } //消費者
void ConsumerThread(LPVOID param) { while (TRUE) { //看Event是否允許生產,不允許無限等待
 WaitForSingleObject(hEvent2, INFINITE); if (store.size() > 0) { int id = store.front();  //獲取第一個貨物的ID,隊列先進先出
            store.pop();             //取出貨物,騰出空間
            printf(" 取出貨物:%d\n", id); Sleep(arr2[id % 10] * 1000);   //生產速度不確定
 } else//倉庫空了
 { ResetEvent(hEvent2);//設為無信號,不能取貨物
            printf("倉庫空了!\n"); } if (store.size() < 3)//說明倉庫沒滿,可以繼續生產
 { SetEvent(hEvent1); } } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM