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;
}
Osobiste