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