C语言实现PV操作典型程序

C语言实现PV操作典型程序

PV操作是典型的同步机制之一。用一个信号量与一个消息联系起来,当信号量的值为0时,表示期望的消息尚未产生;当信号量的值非0时,表示期望的消息已经存在。用PV操作实现进程同步时,调用P操作测试消息是否到达,调用V操作发送消息。

概念

临界区**指的是一个访问共用资源(例如:共用设备或是共用存储器)的程序片段,而这些共用资源又无法同时被多个线程访问的特性。

临界区调度原则:

1、如果有若干进程要求进入空闲的临界区,一次仅允许一个进程进入。

2、任何时候,处于临界区内的进程不可多于一个。如已有进程进入自己的临界区,则其它所有试图进入临界区的进程必须等待。

3、进入临界区的进程要在有限时间内退出,以便其它进程能及时进入自己的临界区。

4、如果进程不能进入自己的临界区,则应让出CPU,避免进程出现“忙等”现象。

信号量(semaphore): 可用于进程间同步也可用于同一个进程间的线程同步。

信号量有一个使用计数器,这个使用计数器,是信号量的最大资源计数和当前资源计数的差值。

计数器的值大于0时,表示当前可用资源个数。

计数器的值小于0时,表等待使用资源的进程个数。

计数器的值为0则既没有可用资源也没有等待资源的进程

假设S的为信号量的计数器的值:

P操作:执行一次P操作意味着请求分配一个单位的资源,因此S的值减1,当S<0时,表示已经没有可用资源,请求者必须等待别的进程释放该类资源,它才能继续运行。
V操作:执行一次V操作意味着释放一个资源,因此S的值加1,当S<0,表示有某些进程正在等待资源,因此要唤醒一个等待状态的进程,使之继续运行。

实例

PV操作解决问题可以套用一个固定的代码demo~就是一个while里套三个部分:开头一个P结尾一个V中间是临界区,

C语言实现PV操作典型程序

C语言实现PV操作典型程序

使用PV操作来解决问题:爸爸放苹果,女儿拿苹果,妈妈放橘子,儿子拿橘子。

由题可以看出需要4个进程,爸爸和妈妈的进程需要执行放的操作,我们分别套用模型即可

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include<semaphore.h>


#define P sem_wait
#define V sem_post 
#define full_apple &fullA
#define full_orange &fullB
#define empty &empty_aha


sem_t fullA;
sem_t fullB;
sem_t empty_aha;
int num=0; 



void* Dad(void *p)
{
    while(num<50)
    { 
        P(empty);  
	    num++;
        printf("老爸放了个苹果%d\n",num);
        V(full_apple);
    }
}


void* Dangter(void *p)
{
    while(num<50)
    {
        P(full_apple);
		num++;               
         printf("女儿吃了个苹果%d\n",num);
        V(empty);
    }
}

void* Mum(void *p)
{
    while(num<50)
    { 
        P(empty);  
	    num++;
        printf("老妈放了个橘子%d\n",num);
        V(full_orange);
    }
}


void* Son(void *p)
{
    while(num<50)
    {
        P(full_orange);
		num++;               
        printf("儿子吃了个橘子%d\n",num);
        V(empty);
    }
}

int main()
{
    
    sem_init(full_apple, 0, 0);
    sem_init(full_orange, 0, 0);   
    sem_init(empty, 0, 1);   
 
    pthread_t tid0;
    pthread_t tid1;
    pthread_t tid2;
    pthread_t tid3;
    pthread_create(&tid0, NULL, Dad, NULL);
    pthread_create(&tid1, NULL, Mum, NULL);
    pthread_create(&tid2, NULL, Son, NULL);
    pthread_create(&tid3, NULL, Dangter, NULL);
    getchar();
    pthread_exit(0);
    return 0;
}

上一篇:CentOS下LVM分区简介


下一篇:Linux LVM学习总结——删除PV遇到的问题小结