[オペレーティングシステム] - 同期の消費者生産者問題

生産者と消費者の同期については、オペレーティング・システムは、より古典的な問題です。インタビューの最初のポイントで審査を使用すると、生産者 - 消費者モデルは、第二の点は、あなたのモデルシーンの使用を与え、その後のコードを実装します言わせて通常です。この記事では〜彼らはそれを理解することを学ぶみましょう

まず、生産者-消費者モデルを記述する
別の、(スレッド)が「生産者」などの1つのまたは複数のプロセス(スレッド)は、バッファにデータを追加し続けるのと同じバッファを共有する2つの以上のプロセスをまたはバッファからデータを取得するための「消費者」としての複数のプロセス(スレッド)。注目のそのモデルは以下の通りであります:

  • 生産者と消費者は、バッファの相互に排他的な使用でなければなりません
  • バッファが空である、消費者がデータを読み取ることができません
  • バッファがいっぱいになると、プロデューサーは、データを追加することはできません

第二に、モデルの利点は
デカップリング(1)
複数のバッファよりは、生産者と消費者との間の強い結合が解か、生産者及びバッファ、バッファ消費者の間の弱い結合になります。
(2)支持体の同時
生産者と消費者は、2つの独立した同時被写体であってもよいです。生産者がバッファにデータにより作成された追加、あなたはデータの次の生産に行くことができます。消費者は、それがプロデューサーを待つ必要がない、バッファからデータを読み出すために、同じです。このように、生産者と消費者が同時に実行することができます。
(3)多忙な凹凸をサポート
追加生産者だけバッファにデータを生成する必要がある、バッファがフル生産ではありません。消費者データがバッファから読み出され、バッファは、消費されていない空であるので、ダイナミックバランスのプロデューサ/コンシューマの処理能力。

第三に、なお、キーポイント
生産者と消費者を再利用することができるバッファのサイズがnであると仮定すると(1)(メモリセルの、すなわち数)。
(2)以下に示すように、メモリセルのデータのフェッチ記憶プロデューサとコンシューマデータ記憶部を指し、二つのポインタとOUTに設けられています。
ここに画像を挿入説明
バッファにデータを書き込むことができない(3)生産者は、消費者は、生産者と消費者と同期する必要があり、空のバッファ内のデータを取ることができない、完全です。また、あなたが同期制御を行わない場合には、生産者と消費者は、メモリセルを読み書きしながらも、おそらく、バッファを入力することができ、不確実な結果の実現につながります。

第四に、問題の分析
:次のように実行フローをまとめると
ここに画像を挿入説明
ここに画像を挿入説明
ここに画像を挿入説明
V.コードの実装を

特定の問題シーン記述:
int型の配列を仮定し、N = 10個の要素があります。配列は、今のバッファに書き込みデータにプロデューサーとして3つのスレッドではなく、ランダムな数秒を作成し、バッファゾーンに応じて、その後、バッファや印刷物からデータを取るために、消費者などの2つのスレッドが、数秒ごとに作成されます。(ランダム関数は、スリープ(M)を使用して数秒待って、使用するM =ランド()であってもよい)
:補充知識
(1)sem_t:長い整数の性質であるタイプsem_tのセマフォデータ構造。
(2)関数sem_post(sem_t * SEM)セマフォの値を増加させるため。
(3)関数sem_wait(sem_t * SEM)は、セマフォ値が0 SEM SEMマイナス値をブロッキングした後、放出さよりも大きくなるまで、現在のスレッドをブロックするために使用された共通のリソースを使用することによって低減示し
する#include <pthread.hの(4) > //スレッド関連のヘッダファイルをインクルードする#include <semaphore.h> //含まれているセマフォ関連するヘッダファイル
(5)のpthread_createは、スレッド関数を作成します
(6)pthread_joinをスレッド作成者が子プロセスの実行終了時にそのリソースを回復

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<semaphore.h>
#include<string.h>
#include<sys/sem.h>
sem_t s;//互斥信号量,控制对缓冲区的访问
sem_t n;//计数信号量,缓冲区中数据个数
sem_t e;//计数信号量,缓冲区空余单元个数
注意!到底有没有空间写或者有没有数据读,用e,n控制,不必再看in、out
int buffsize[10] = {0};
int  in = 0;//控制缓存区写的位置
int out =0;//控制缓存区取数据的位置
注意!他们的位置是不会发生跳跃的,是一个一个顺序写的,写到末尾再回头从第一个写

void* Producers()
{
      while(1)
       {
              srand(time(NULL));//初始化种子,这个表示每秒递增1
              int data = rand() % 11;
              sem_wait(&e);
              sem_wait(&s);
              buffsize[in] = data;
              printf("%d""%d",in,data);
              in = (in+1) % 10;
              sem_post(&s);
              sem_post(&n);
              sleep(2);
       }
}

void*Consumers()
{
       while(1)
       {
             sem_wait(&n);
              sem_wait(&s);
              printf("%d""%d",out,buffsize[out]);
              buffsize[out] = 0;
              out =(out+1) % 10;
              sem_post(&e);
              sem_post(&s);
              sleep(2);
       }
}

int main()
{
       pthread_t      P1,P2,P3,C1,C2;
       sem_init(&s,0,1);
       sem_init(&s,0,0);
       sem_init(&s,0,10);
       pthread_create(&P1,NULL,Producers,NULL);
       pthread_create(&P2,NULL,Producers,NULL);
       pthread_create(&P3,NULL,Producers,NULL);
       pthread_create(&C1,NULL,Consumers,NULL);
       pthread_create(&C2,NULL,Consumers,NULL);
       pthread_join(P1,NULL);
       pthread_join(P2,NULL);
       pthread_join(P3,NULL);
       pthread_join(C1,NULL);
       pthread_join(C2,NULL);
       sem_destroy(&s);
       sem_destroy(&n);
       sem_destroy(&e);
       exit(0);
}
公開された25元の記事 ウォンの賞賛5 ビュー1574

おすすめ

転載: blog.csdn.net/qq_43412060/article/details/104291218