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中間是臨界區,
使用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;
}