SO:Semafor
Z Wiki Rafał (ert16) Trójniak
Spis treści |
Opis działania
Przykład składa się z dwóch programów.
writer
- Tworzy pamieć współdzieloną
- Tworzy semafor, inicjalizuje go wartością 1
- Zapisuje do bufora 3 różne ciągi znaków, zabezpieczając podczas zapisu semaforem dostęp do danych.
- Usuwa semafor
reader_pure
- Pobiera pamięć współdzieloną
- Pobiera semafor, lub czeka jeśli nie istnieje
- Pobiera string z pamięci współdzielonej
- Porównuje i kończy pracę przy znalezieniu błędnej wartości
reader
- Pobiera pamięć współdzieloną
- Pobiera semafor, lub czeka jeśli nie istnieje
- Pobiera string z pamięci współdzielonej, zabezpieczając dostęp do pamięci przy pomocy semafora
- Porównuje i zlicza błędne porównania
Kody źródłowe
sem.c
key_t getKey() { key_t key; key = ftok("id", 'R'); if ( key==-1){ perror("ftok"); exit(1); } return key; } int shmId() { int shmid = shmget(getKey(), 1024, 0644 | IPC_CREAT); if ( shmid ==-1){ perror("shmget"); exit(1); } return shmid; } char * teksty[]={ "..............", "^^^^^^^^^^^^^^", "**************"};
writer.c
#define _XOPEN_SOURCE #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <sys/shm.h> #include <sys/sem.h> #include <errno.h> #include "sem.c" int main(int argc, char * argv[]) { int shmid=shmId(); int semid; char * data; unsigned i,l; struct sembuf lock,unlock; /* Inicjalizacja komend */ unlock.sem_num=0; unlock.sem_op = 1; unlock.sem_flg= 0; lock.sem_num=0; lock.sem_op = -1; lock.sem_flg= 0; printf("Geting shared memory\n"); data = shmat(shmid, (void *)0, 0); if (data == (char *)(-1)) { perror("shmat"); exit(1); } printf("Geting Semaphore\n"); semid = semget(getKey(), 0, 0); if(semid==-1) { printf("Creating Semaphore\n"); semid = semget(getKey(), 1, 0660 | IPC_CREAT); if(semop(semid,&unlock,1)) { printf("errno:%u\n",errno); perror("semop"); exit(0); } } printf("SemId : %u\n",semid); printf("ShmId : %u\n",shmid); for(i=0;i<1000;i++) { for(l=0;l<sizeof(teksty)/sizeof(char *);l++) { unsigned c; /* Locing */ if(semop(semid,&lock,1)) { perror("semop"); break; } /* Przepisujemy do pamięci współdzielonej*/ for(c=0;data[c]=teksty[l][c];c++) usleep(1); /* Unlock */ if(semop(semid,&unlock,1)) { perror("semop"); break; } } } /* Usuwam semafor */ if (semctl(semid, 0, IPC_RMID, l) == -1) { perror("semctl"); exit(1); } return 0; }
reader_pure.c
#define _XOPEN_SOURCE #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/sem.h> #include "sem.c" char buf[30]; int main(int argc, char * argv[]) { int shmid=shmId(); unsigned l,max,cycles=0; char * data; printf("Geting shared memory\n"); data = shmat(shmid, (void *)0, SHM_RDONLY); if (data == (char *)(-1)) { perror("shmat"); exit(1); } printf("Running\n"); while ( 1 ) { /* Copying */ strcpy(buf,data); /* Comparision */ max=sizeof(teksty)/sizeof(char *); for(l=0;l<max;l++) { if(strcmp(buf,teksty[l])==0){ max=l; break; } } if(max==3) { printf("%s\n",buf); break; } /* Counting */ cycles++; } printf("%u cycles\n",cycles); return 0; }
reader.c
#define _XOPEN_SOURCE #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/sem.h> #include "sem.c" char buf[30]; int main(int argc, char * argv[]) { int shmid=shmId(); int semid; unsigned l,max,cycles=0; char * data; struct sembuf lock,unlock; /* Inicjalizacja komend */ unlock.sem_num=0; unlock.sem_op = 1; unlock.sem_flg= 0; lock.sem_num=0; lock.sem_op = -1; lock.sem_flg= 0; printf("Geting shared memory\n"); data = shmat(shmid, (void *)0, SHM_RDONLY); if (data == (char *)(-1)) { perror("shmat"); exit(1); } printf("Geting Semapthore\n"); do { semid = semget(getKey(), 0, 0); if(semid==-1) { printf("Waiting..\n"); sleep(1); } }while(semid==-1); printf("Running\n"); while ( 1 ) { /* Locking */ if(semop(semid,&lock,1)) { perror("semop"); break; } /* Copying */ strcpy(buf,data); /* Unlocking */ if(semop(semid,&unlock,1)) { perror("semop"); break; } /* Comparision */ max=sizeof(teksty)/sizeof(char *); for(l=0;l<max;l++) { if(strcmp(buf,teksty[l])==0){ max=l; break; } } if(max==3) printf("%s",buf); /* Counting */ cycles++; } printf("%u cycles\n",cycles); return 0; }