为什么我的生产者 - 消费者阻止?

时间:2016-01-28 12:48:18

标签: c linux shared-memory semaphore producer-consumer

这是生产者 - 消费者问题的简单(几乎)解决方案。 它使用等待和信号功能,但可能会阻止其中一个等待。

以下是我的文件: prod.c

int *pam;
#define MAX 10
#define MAX2 12
#define PUSTY 2 //EMPTY
#define S1 0
#define PELNY 1 //FULL
#define zapis pam[MAX+1] //write
#define odczyt pam[MAX] //read
int main() {

        int i;
        time_t czas;
        key_t klucz, kluczm;
        int semID;
        int shmID;
        int N=3;

        printf("producer--------------------------------\n");
        if((klucz=ftok(".", 'A')) == -1)
                {printf("Blad ftok (A)\n"); exit(2);};

        semID=alokujSem(klucz, N, IPC_CREAT | 0666);
        if(semID==-1)
                {printf("blad semafora - producent\n");exit(1);}

        kluczm=ftok(".", 'B');
        shmID=shmget(kluczm, MAX2*sizeof(int), IPC_CREAT | 0666);
        if(shmID==-1)
                {printf("blad pamieci dzielonej - producent\n");exit(1);}

        pam=(int*)shmat(shmID, NULL, 0);

        time(&czas);
        i=((int)czas)%100;

        waitSemafor(semID, PUSTY, 0);
        waitSemafor(semID, S1, 0);

        pam[zapis]=i;
        zapis=(zapis+1)%MAX;
        printf("Wyprodukowano: %d\n", pam[zapis]);

        signalSemafor(semID, S1);
        signalSemafor(semID, PELNY);

        printf("Po signal - producent\n");

}

kons.c

int *pam;
#define MAX 10
#define MAX2 12
#define PUSTY 2 //EMPTY
#define S1 0
#define PELNY 1 //FULL
#define zapis pam[MAX+1] //write
#define odczyt pam[MAX] //read

int main()
{
        key_t klucz, kluczm;
        int semID, shmID;
        int i;
        int N =3;

        printf("consumer------------------------------------\n");
        if( (klucz=ftok(".", 'A')) == -1)
        {
                printf("BLad frok(A)\n");
                exit(2);
        }

        semID=alokujSem(klucz, N, IPC_CREAT | 0666);//allocate semaphores
        if(semID==-1)
                {printf("blad semafora-konsument\n"); exit(1);};
        klucz = ftok(".", 'B');
        shmID = shmget(kluczm, MAX2*sizeof(int), IPC_CREAT|0666);//adding to shared memory
        if(shmID==-1)
                {printf("blad pamieci dzielonej-konsument\n");exit(1);};
        pam=(int*)shmat(shmID, NULL, 0);

        waitSemafor(semID, PELNY, 0);
        waitSemafor(semID, S1, 0);

        printf("konsumuje %d \n",pam[odczyt]);
        odczyt=(odczyt+1)%MAX;

        signalSemafor(semID, S1);
        signalSemafor(semID, PUSTY);

        printf("Konsument skonczyl\n");
}

operacje.c

int alokujSem(key_t klucz, int number, int flagi) {
   int semID;
   if((semID=semget(klucz, number, flagi)) == -1)
           {perror("Blad semget (alokujsemafor): "); exit(1); }
   return semID;
}

int zwolnijSem(int semID, int number) {
   return semctl(semID, number, IPC_RMID, NULL);
}

void inicjalizujSem(int semID, int number, int val) {
   if(semctl(semID, number, SETVAL, val) == -1)
       {perror("Blad semctl (inicjalizujsemafor): "); exit(1);}
}

int waitSemafor(int semID, int number, int flags)
{
   printf("Wszedłem do wait z numerem %d", number);
   struct sembuf operacje[1];
   operacje[0].sem_num = number;
   operacje[0].sem_op = -1;
   operacje[0].sem_flg = SEM_UNDO;

   if ( semop(semID, operacje, 1) == -1 )
   {
      printf("Semop error: %s\n", strerror(errno));
      perror("Blad semop (waitSemafor)");
      return -1;
   }

   return 1;
}

void signalSemafor(int semID, int number)
{
   struct sembuf operacje[1];
   operacje[0].sem_num = number;
   operacje[0].sem_op = 1;
   operacje[0].sem_flg = SEM_UNDO;

   if (semop(semID, operacje, 1) == -1 )
      perror("Blad semop (postSemafor): ");
}

我不知道为什么,但它甚至没有从waitSemafor()打印printf(“...”)。

和mainp.c

#define P 2 // processes amount
#define MAX 10
#define MAX2 12
#define PUSTY 2 //EMPTY
#define S1 0
#define PELNY 1 //FULL

int main() {
   key_t klucz, kluczm;
   int semID;
   int shmID;
   int i;
   int N=3;

   if ( (klucz = ftok(".", 'A')) == -1 )
   {
      printf("Blad ftok (main)\n");
      exit(1);
   }

   semID=alokujSem(klucz, N, IPC_CREAT | IPC_EXCL | 0666);

   inicjalizujSem(semID, S1, 1);
   inicjalizujSem(semID, PELNY, 0);
   inicjalizujSem(semID, PUSTY, MAX);
   printf("Semaphore ready!\n");

   kluczm=ftok(".",'B');
   shmID=shmget(kluczm, MAX2*sizeof(int), IPC_CREAT|IPC_EXCL|0666);

   for(i=0; i< P; i++)
        switch(fork())
        {
        case -1:
                perror("Blad fork(mainprog)");
                exit(2);
        case 0:
                execl("./prod", "prod", NULL);
        }
   for(i=0; i<P; i++)
        switch(fork())
        {
        case -1:
                printf("Blad fork (mainprog)\n");
                exit(2);
        case 0:
                execl("./kons", "kons", NULL);
        }


   for(i=0; i<2*P;i++) {
           wait(NULL);
   }
   zwolnijSem(semID,N); //release semaphore
   shmctl(shmID,IPC_RMID, NULL);
   printf("MAIN: Koniec.\n");
}

打印到控制台的唯一因素是:

  

信号量准备好了!   消费者 - - - - - - - - - - - - - - - - - -   消费者 - - - - - - - - - - - - - - - - - -   制片人--------------------------------   生产者--------------------------------

它挂在那里。订单也很奇怪,生产者应该是第一位。

我使用gcc编译它,它看起来像这样:

  
      
  • gcc -c -o operacje operacje.c
  •   
  • gcc -o kons kons.c operacje
  •   
  • gcc -o prod prod.c operacje
  •   
  • gcc -o mainp mainp.c operacje
  •   
  • 然后运行“./mainp”
  •   

我将非常感谢任何想法或解决方案。

0 个答案:

没有答案