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);
        }
    }
}

 

posted @ 2020-04-18 21:33  坦坦荡荡  阅读(2724)  评论(0编辑  收藏  举报