0

That's simple (almost)solution to producer-consumer problem. It uses wait and signal functions, but probably blocks on one of the waits.

Here are my files: 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): ");
}

I don't know why, but it doesn't even print the printf("...") from waitSemafor().

and 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");
}

The only thins that are printed to console are:

Semaphore ready! consumer------------------------------------ consumer------------------------------------ producer-------------------------------- producer--------------------------------

and it hangs right there. Order is also strange, producer should be first.

I use gcc to compile it, and it looks like this:

  • gcc -c -o operacje operacje.c
  • gcc -o kons kons.c operacje
  • gcc -o prod prod.c operacje
  • gcc -o mainp mainp.c operacje
  • and then run "./mainp"

I will be very grateful for any ideas or solutions.

xukay
  • 1
  • 1
  • Ok, that's all about that I forgot to add #include to files. – xukay Jan 29 '16 at 00:37
  • regarding this kind of line: `#define PUSTY 2 //EMPTY` a comment should not be on the same line as a macro definition. Because the comment will be included in the `text replacement` operation and can cause some very difficult bugs to debug. Suggest placing comments on the prior line, before the macro definition. – user3629249 Jan 30 '16 at 02:25
  • when indenting code, never use tabs. because each wordprocessor/editor has the tab stops/tab width set differently. Suggest using 4 spaces per indent level as that is visible even with variable width fonts and allows for many indent levels across the page – user3629249 Jan 30 '16 at 02:29
  • to start, you need a header file that contains the prototypes for the functions in the `operacje.c` file. Then that header file needs to be included each of the other .c files that calls any of those functions. With out that header file and the related #include statements, the posted code does not cleanly compile, resulting several compiler warning messages similar to: `warning: implicit declaration of function 'signalSemafor' [-Wimplicit-function-declaration]` (cont) – user3629249 Jan 30 '16 at 02:38
  • The compiler, at best, will assume that the parameters and any return type are all `int`. The result is invalid code that can be extremely difficult to debug. When compiling, always enable all the warnings, then fix those warnings. (for gcc, at a minimum use: `-Wall -Wextra -pedantic` (I also use: `-Wconversion -std=c99` ) ) – user3629249 Jan 30 '16 at 02:39
  • when coding, for ease of understanding and readability by us humans, please follow the axiiom: *only one statement per line and (at most) one variable declaration per statement.* – user3629249 Jan 30 '16 at 02:47
  • the file: `operacje.c` is missing the header file for the definition of `key_t` – user3629249 Jan 30 '16 at 02:51
  • regarding these two lines: `printf("Semop error: %s\n", strerror(errno)); perror("Blad semop (waitSemafor)");` the value of `errno` will be changed by the call to `printf()` so the call to `perror()` will output the wrong message. Suggest reversing those two lines. – user3629249 Jan 30 '16 at 02:52
  • in function: `signalSemafor()` this line: `perror("Blad semop (postSemafor): ");` should be: `perror("Blad semop (signalSemafor): ");` – user3629249 Jan 30 '16 at 02:56
  • there are LOTS more problems in the code, ranging from missing #include statements to missing definition of: `struct sembuf_operacje` – user3629249 Jan 30 '16 at 02:59

0 Answers0