5. IPC

5.1. Pamięć współdzielona

Listing 5.1: Zapis bufora cyklicznego (str. 36 – 37)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define MAX 10

main(){
   int shmid, i;
   int *buf;
   
   shmid = shmget(45281, MAX*sizeof(int), IPC_CREAT|0600);
   if (shmid == -1){
      perror("Utworzenie segmentu pamieci wspoldzielonej");
      exit(1);
   }
   
   buf = (int*)shmat(shmid, NULL, 0);
   if (buf == NULL){
      perror("Przylaczenie segmentu pamieci wspoldzielonej");
      exit(1);
   }

   for (i=0; i<10000; i++)
      buf[i%MAX] = i;
}

Listing 5.2: Odczyt bufora cyklicznego (str. 37)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define MAX 10

main(){
   int shmid, i;
   int *buf;
   
   shmid = shmget(45281, MAX*sizeof(int), IPC_CREAT|0600);
   if (shmid == -1){
      perror("Utworzenie segmentu pamieci wspoldzielonej");
      exit(1);
   }
   
   buf = (int*)shmat(shmid, NULL, 0);
   if (buf == NULL){
      perror("Przylaczenie segmentu pamieci wspoldzielonej");
      exit(1);
   }

   for (i=0; i<10000; i++)
      printf("Numer: %5d   Wartosc: %5d\n", i, buf[i%MAX]);
}

5.2. Semafory

Listing 5.3: Realizacja semafora ogólnego (str. 39)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

static struct sembuf buf;

void podnies(int semid, int semnum){
   buf.sem_num = semnum;
   buf.sem_op = 1;
   buf.sem_flg = 0;
   if (semop(semid, &buf, 1) == -1){
      perror("Podnoszenie semafora");
      exit(1);
   }
}

void opusc(int semid, int semnum){
   buf.sem_num = semnum;
   buf.sem_op = -1;
   buf.sem_flg = 0;
   if (semop(semid, &buf, 1) == -1){
      perror("Opuszczenie semafora");
      exit(1);
   }
}

Listing 5.4: Synchronizacja producenta w dostępie do bufora cyklicznego (str. 40)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>

#define MAX 10

main(){
   int shmid, semid, i;
   int *buf;
   
   semid = semget(45281, 2, IPC_CREAT|0600);
   if (semid == -1){
      perror("Utworzenie tablicy semaforow");
      exit(1);
   }
   if (semctl(semid, 0, SETVAL, (int)MAX) == -1){
      perror("Nadanie wartosci semaforowi 0");
      exit(1);
   }
   if (semctl(semid, 1, SETVAL, (int)0) == -1){
      perror("Nadanie wartosci semaforowi 1");
      exit(1);
   }
   
   shmid = shmget(45281, MAX*sizeof(int), IPC_CREAT|0600);
   if (shmid == -1){
      perror("Utworzenie segmentu pamieci wspoldzielonej");
      exit(1);
   }
   
   buf = (int*)shmat(shmid, NULL, 0);
   if (buf == NULL){
      perror("Przylaczenie segmentu pamieci wspoldzielonej");
      exit(1);
   }

   for (i=0; i<10000; i++){
      opusc(semid, 0);
      buf[i%MAX] = i;
      podnies(semid, 1);
   }
}

Listing 5.5: Synchronizacja konsumenta w dostępie do bufora cyklicznego (str. 41)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>

#define MAX 10

main(){
   int shmid, semid, i;
   int *buf;
   
   semid = semget(45281, 2, 0600);
   if (semid == -1){
      perror("Uzyskanie identyfikatora tablicy semaforow");
      exit(1);
   }

   shmid = shmget(45281, MAX*sizeof(int), 0600);
   if (shmid == -1){
      perror("Uzyskanie identyfikatora segmentu pamieci wspoldzielonej");
      exit(1);
   }
   
   buf = (int*)shmat(shmid, NULL, 0);
   if (buf == NULL){
      perror("Przylaczenie segmentu pamieci wspoldzielonej");
      exit(1);
   }

   for (i=0; i<10000; i++){
      opusc(semid, 1);
      printf("Numer: %5d   Wartosc: %5d\n", i, buf[i%MAX]);
      podnies(semid, 0);
   }
}

Listing 5.6: Synchronizacja wielu producentów w dostępie do bufora cyklicznego (str. 42 – 43)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>

#define MAX 10

main(){
   int shmid, semid, i;
   int *buf;
   
   shmid = shmget(45281, (MAX+2)*sizeof(int), IPC_CREAT|0600);
   if (shmid == -1){
      perror("Utworzenie segmentu pamieci wspoldzielonej");
      exit(1);
   }
   
   buf = (int*)shmat(shmid, NULL, 0);
   if (buf == NULL){
      perror("Przylaczenie segmentu pamieci wspoldzielonej");
      exit(1);
   }
   
   #define indexZ buf[MAX]
   #define indexO buf[MAX+1]

   semid = semget(45281, 4, IPC_CREAT|IPC_EXCL|0600);
   if (semid == -1){
      semid = semget(45281, 4, 0600);
      if (semid == -1){
         perror("Utworzenie tablicy semaforow");
         exit(1);
      }
   }
   else{
      indexZ = 0;
      indexO = 0;
      if (semctl(semid, 0, SETVAL, (int)MAX) == -1){
         perror("Nadanie wartosci semaforowi 0");
         exit(1);
      }
      if (semctl(semid, 1, SETVAL, (int)0) == -1){
         perror("Nadanie wartosci semaforowi 1");
         exit(1);
      }
      if (semctl(semid, 2, SETVAL, (int)1) == -1){
         perror("Nadanie wartosci semaforowi 2");
         exit(1);
      }
      if (semctl(semid, 3, SETVAL, (int)1) == -1){
         perror("Nadanie wartosci semaforowi 3");
         exit(1);
      }
   }
   
   for (i=0; i<10000; i++){
      opusc(semid, 0);
      opusc(semid, 2);
      buf[indexZ] = i;
      indexZ = (indexZ+1)%MAX;
      podnies(semid, 2);
      podnies(semid, 1);
   }
}

Listing 5.7: Synchronizacja wielu konsumentów w dostępie do bufora cyklicznego (str. 43 – 44)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>

#define MAX 10

main(){
   int shmid, semid, i;
   int *buf;
   
   shmid = shmget(45281, (MAX+2)*sizeof(int), IPC_CREAT|0600);
   if (shmid == -1){
      perror("Utworzenie segmentu pamieci wspoldzielonej");
      exit(1);
   }
   
   buf = (int*)shmat(shmid, NULL, 0);
   if (buf == NULL){
      perror("Przylaczenie segmentu pamieci wspoldzielonej");
      exit(1);
   }
   
   #define indexZ buf[MAX]
   #define indexO buf[MAX+1]

   semid = semget(45281, 4, IPC_CREAT|IPC_EXCL|0600);
   if (semid == -1){
      semid = semget(45281, 4, 0600);
      if (semid == -1){
         perror("Utworzenie tablicy semaforow");
         exit(1);
      }
   }
   else{
      indexZ = 0;
      indexO = 0;
      if (semctl(semid, 0, SETVAL, (int)MAX) == -1){
         perror("Nadanie wartosci semaforowi 0");
         exit(1);
      }
      if (semctl(semid, 1, SETVAL, (int)0) == -1){
         perror("Nadanie wartosci semaforowi 1");
         exit(1);
      }
      if (semctl(semid, 2, SETVAL, (int)1) == -1){
         perror("Nadanie wartosci semaforowi 2");
         exit(1);
      }
      if (semctl(semid, 3, SETVAL, (int)1) == -1){
         perror("Nadanie wartosci semaforowi 3");
         exit(1);
      }
   }

   for (i=0; i<10000; i++){
      opusc(semid, 1);
      opusc(semid, 3);
      printf("Numer: %5d   Wartosc: %5d\n", i, buf[indexO]);
      indexO = (indexO+1)%MAX;
      podnies(semid, 3);
      podnies(semid, 0);
   }
}

5.3. Kolejki komunikatów

Listing 5.8: Impelmentacja zapisu ograniczonego bufora za pomocą kolejki komunikatów (str. 45)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define MAX 10

struct buf_elem {
   long mtype;
   int mvalue;
};

#define PUSTY 1
#define PELNY 2

main(){
   int msgid, i;
   struct buf_elem elem;
   
   msgid = msgget(45281, IPC_CREAT|IPC_EXCL|0600);
   if (msgid == -1){
      msgid = msgget(45281, IPC_CREAT|0600);
      if (msgid == -1){
         perror("Utworzenie kolejki komunikatow");
         exit(1);
      }
   }
   else{
      elem.mtype = PUSTY;
      for (i=0; i<MAX; i++)
         if (msgsnd(msgid, &elem, sizeof(elem.mvalue), 0) == -1){
            perror("Wyslanie pustego komunikatu");
            exit(1);
         }
   }

   for (i=0; i<10000; i++){
      if (msgrcv(msgid, &elem, sizeof(elem.mvalue), PUSTY, 0) == -1){
         perror("Odebranie pustego komunikatu");
         exit(1);
      }
      elem.mvalue = i;
      elem.mtype = PELNY;
      if (msgsnd(msgid, &elem, sizeof(elem.mvalue), 0) == -1){
         perror("Wyslanie elementu");
         exit(1);
      }
   }
}

Listing 5.9: Impelmentacja odczytu ograniczonego bufora za pomocą kolejki komunikatów (str. 46 – 47)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define MAX 10

struct buf_elem {
   long mtype;
   int mvalue;
};
#define PUSTY 1
#define PELNY 2

main(){
   int msgid, i;
   struct buf_elem elem;
   
   msgid = msgget(45281, IPC_CREAT|IPC_EXCL|0600);
   if (msgid == -1){
      msgid = msgget(45281, IPC_CREAT|0600);
      if (msgid == -1){
         perror("Utworzenie kolejki komunikatow");
         exit(1);
      }
   }
   else{
      elem.mtype = PUSTY;
      for (i=0; i<MAX; i++)
         if (msgsnd(msgid, &elem, sizeof(elem.mvalue), 0) == -1){
            perror("Wyslanie pustego komunikatu");
            exit(1);
         }
   }

   for (i=0; i<10000; i++){
      if (msgrcv(msgid, &elem, sizeof(elem.mvalue), PELNY, 0) == -1){
         perror("Odebranie elementu");
         exit(1);
      }
      printf("Numer: %5d   Wartosc: %5d\n", i, elem.mvalue);
      elem.mtype = PUSTY;
      if (msgsnd(msgid, &elem, sizeof(elem.mvalue), 0) == -1){
         perror("Wyslanie pustego komunikatu");
         exit(1);
      }
   }
}

Spis treści

Poprzedni temat

4. Łącza

Następny temat

6. Sygnały

Ta strona