C言語でのPV操作の典型的なプログラム
PV操作は、一般的な同期メカニズムの1つです。セマフォをメッセージに接続します。セマフォの値が0の場合は、目的のメッセージが生成されていないことを意味し、セマフォの値が0でない場合は、目的のメッセージがすでに存在していることを意味します。PV操作を使用してプロセスの同期を達成すると、P操作が呼び出されてメッセージが到着するかどうかがテストされ、V操作を使用してメッセージが送信されます。
コンセプト
重要なセクション**は、共有リソース(共有機器や共有メモリなど)にアクセスするプログラムセグメントを指します。これらの共有リソースには、複数のスレッドが同時にアクセスすることはできません。
クリティカルエリアのスケジューリング原則:
1.アイドル状態のクリティカルセクションへのアクセスを必要とするプロセスが複数ある場合、一度に1つのプロセスしか入力できません。
2.クリティカルゾーンには、常に1つのプロセスしか存在できません。既存のプロセスが独自のクリティカルセクションに入る場合、クリティカルセクションに入ろうとする他のすべてのプロセスは待機する必要があります。
3.他のプロセスが時間内にクリティカルセクションに入ることができるように、クリティカルセクションに入るプロセスは限られた時間内に終了する必要があります。
4.プロセスが独自の重要な領域に入ることができない場合、「ビジー待機」現象のプロセスを回避するためにCPUを放棄する必要があります。
セマフォ:同じプロセス間のプロセス間同期またはスレッド同期に使用できます。
セマフォには使用カウンタがあり、この使用カウンタは、セマフォの最大リソース数と現在のリソース数の差です。
カウンターの値が0より大きい場合、それは使用可能なリソースの現在の数を示します。
カウンターの値が0未満の場合、テーブルはリソースを使用しているプロセスの数を待機します。
カウンター値0は、使用可能なリソースも、リソースを待機しているプロセスもないことを意味します
Sがセマフォのカウンターの値であるとします。
P操作:P操作を実行すると、リソースのユニットの割り当てを要求することになるため、Sの値は1だけ減ります。S<0の場合、使用可能なリソースがないことを意味します。リクエスターは、続行する前に、このタイプのリソースを解放するために別のプロセスを待つ必要があります。実行しています。
V操作:V操作を実行すると、リソースが解放されるため、Sの値が1増加します。S<0の場合、あるプロセスがリソースを待機しているため、実行を継続するためにプロセスを待機状態でウェイクアップする必要があります。
例
PV動作の問題を解決するために、固定コードのデモを適用できます。しばらくすると、最後にP、最後にV、中央にクリティカルセクションの3つの部分があります。
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;
}