天天看點

生産者消費者實作

  生産者消費者的實驗布置一周了,還不知怎麼寫,主要是些資訊量的操作wait()signal()函數不會用。在網上找了一個源程式,包括windows下和linux下的具體實作。

  把人家的東西帖過來,儲存住。我隻看了下linux下的程式,有些函數及其參數還是看不太   懂。一會把這個程式涉及的一些問題的相關知識貼在後幾篇文章,學習。。。。

他的程式實作了有一個生産者程序,有兩個消費者程序。生産者産生1-100的100個數。兩個消費者從共享記憶體中取數。

以下程式轉載于:[url]http://www.5inet.net/System/Linux/025896.html[/url](作業系統中關于信号量操作的代碼示例(Linux + windows))author:zhangwei

=======================================

windows下的程式:

#include "stdafx.h"

//作為倉庫存放資料,最多可以放五個資料

int array[5];

//記錄生成資料的個數

int pointer;

//記錄取得的資料的位置

int pointerget;

//用來儲存資料和

int sum;

//臨界區對象

CRITICAL_SECTION csArray;

//句柄,儲存Full信号量

HANDLE hFull;

//句柄,儲存Empty信号量

HANDLE hEmpty;

//生産者函數

DWORD WINAPI Producer(LPVOID lpParam)

{

 int i = 0;

 pointer = 0;

 while( i < 100 )

 {

  WaitForSingleObject(hEmpty,INFINITE);

  EnterCriticalSection( &csArray);

  array[(pointer++)%5] = i + 1;

  LeaveCriticalSection( &csArray);

  ReleaseSemaphore(hFull,1,NULL);

  i++;

 }

 return 0;

}

//消費者函數A

DWORD WINAPI ConsumerA(LPVOID lpParam)

 while(1)

  WaitForSingleObject(hFull,INFINITE);

  sum += array[(pointerget ++ )%5];

  printf("ConsumerA get %d \n",array[(pointerget -1)%5]);

  if(pointerget == 100)

   printf("The sum is %d",sum);

  ReleaseSemaphore(hEmpty,1,NULL);

//消費者函數B

DWORD WINAPI ConsumerB(LPVOID lpParam)

  printf("ConsumerB get %d \n",array[(pointerget -1 )%5]);

//主函數

void main()

 HANDLE hThreadProducer,hThreadConsumerA,hThreadComsumerB;

 sum = 0;

 pointerget = 0;

 InitializeCriticalSection( &csArray);

 hFull = CreateSemaphore(NULL,0,5,NULL);

 hEmpty = CreateSemaphore(NULL,5,5,NULL);

 hThreadProducer = CreateThread(NULL,0,

  Producer,NULL,0,NULL);

 hThreadConsumerA = CreateThread(NULL,0,

  ConsumerA,NULL,0,NULL);

 hThreadComsumerB = CreateThread(NULL,0,

  ConsumerB,NULL,0,NULL);

 _getch();

linux下的程式:

#include <sys/mman.h>

#include <sys/types.h>

#include <linux/sem.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdio.h>

#include <errno.h>

#include <time.h>

#define MAXSEM 5

//聲明三個信号燈ID

int fullid;

int emptyid;

int mutxid;

int main()

  struct sembuf P,V;;

  union semun arg;

  //聲明共享記憶體

  int *array;

  int *sum;

  int *set;

  int *get;

  //映射共享記憶體

  array = (int *)mmap(NULL , sizeof( int )*5,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);

  sum = (int *)mmap(NULL , sizeof( int ),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);

  get = (int *)mmap(NULL , sizeof( int ),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);

  set = (int *)mmap(NULL , sizeof( int ),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);

  *sum = 0;

  *get = 0;

  *set = 0;

  //生成信号燈

  fullid= semget(IPC_PRIVATE,1,IPC_CREAT|00666); 

  emptyid=semget(IPC_PRIVATE,1,IPC_CREAT|00666);

  mutxid=semget(IPC_PRIVATE,1,IPC_CREAT|00666);

  //為信号燈指派

  arg.val = 0;

  if(semctl(fullid , 0 , SETVAL , arg) == -1) perror("semctl setval error");

  arg.val = MAXSEM;

  if(semctl(emptyid , 0 ,SETVAL , arg) == -1) perror("semctl setval error");

  arg.val = 1;

  if(semctl(mutxid , 0 ,SETVAL , arg) == -1) perror("setctl setval error");

  //初始化P,V操作

  V.sem_num=0;

  V.sem_op =1;

  V.sem_flg=SEM_UNDO;

  P.sem_num=0;

  P.sem_op =-1;

  P.sem_flg=SEM_UNDO;

  //生産者程序

  if(fork() == 0 )  {

      int i = 0;

      while( i < 100)

   semop(emptyid , &P ,1 );

   semop(mutxid , &P , 1);

   array[*(set)%MAXSEM] = i + 1;

   printf("Producer %d\n", array[(*set)%MAXSEM]);

   (*set)++;

   semop(mutxid , &V , 1);

   semop(fullid , &V , 1);

   i++; 

       }

      sleep(10);

      printf("Producer is over");

       exit(0);

    }else {

      //ConsumerA  程序

      if(fork()==0) {

        while(1){

   semop(fullid , &P , 1);

   if(*get == 100)

     break;

   *sum += array[(*get)%MAXSEM];

   printf("The ComsumerA Get Number %d\n", array[(*get)%MAXSEM] );

         (*get)++;

   if( *get ==100)

     printf("The sum is %d \n ", *sum);

   semop(emptyid , &V ,1 );

   sleep(1);

 printf("ConsumerA is over");

  exit(0);

      //Consumer B程序

       if(fork()==0) {

         while(1){

   printf("The ComsumerB Get Number %d\n", array[(*get)%MAXSEM] );  

          (*get)++;

  printf("ConsumerB is over");

   exit(0);

     }

    }

  // sleep(20);

  return 0;

張偉的mail:[email protected]

繼續閱讀