#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
/*biblioteka funkcji*/
/*tworze semafor...*/
int StworzSemafor(key_t klucz);
/*inicjalizacja*/
void przyp_wartosc(int semid);
/*opuszczanie semafora*/
void opusc(int semid);
/*podnies semafor*/
void podnies(int semid);
/*usun semafor*/
void usun(int semid);
/*kolejka procesow*/
int ilosc(int semid);
/*dostep*/
key_t dostepSem();
/*tworze pamiec dzielona*/
int pamiecTworz(int id, int rozmiar);
/*uzyskuje dostep do pamieci i zwracam jej ID*/
int dostep(int id);
/*usuwam pamiec */
void usunPam(int id_pam);
/*tworze dowiazanie segmentu pamieci dzielonej i zwracam jego adres*/
void *dowiazanie(int id_pam);
/*usuwam dowiazanie*/
void usunDow(void *id);
/*zwraca rozmiar pamieci dzielonej */
int roz_miar(int id_pam) ;
/*bufor cykliczny*/
typedef struct {
int rozmiar;/*wsk rozmiaru*/
int pocz;/*wsk poczatku*/
int koniec;/*wsk konca*/
char buf[32];/*rozm*/
} cykliczny ;
int main() {
FILE *zrodlo; /*wsk do pliku*/
int i;
char tab[1024];/*tab na wczytanie danych z pliku*/
cykliczny *bufor ; /*wsk do struktury*/
/*semafor*/
int sem1 = StworzSemafor(10) ;
przyp_wartosc(sem1);
/*pamiec dzielona*/
pamiecTworz(8, 1024) ;
/* Inicjalizacja bufora cyklicznego oraz jego dowiazanie */
bufor=(cykliczny*) dowiazanie(dostep(8));/*umieszczenie w pamieci dzielonej*/
bufor[0].rozmiar=0;/*wartosci 0 - wiec pusty*/
bufor[0].pocz=0;
bufor[0].koniec=0;
/*otwieram plik do odczytu*/
zrodlo=fopen("plik.txt", "r") ;
/* Zapis danych do bufora */
while(fgets( tab, 1024, zrodlo ) ) {
for(i = 0 ; i < (strlen(tab)+1) ; i++) { /* przekazywanie pobranych danych do bufora */
opusc(sem1) ; /* opuszczenie semafora do zapisu*/
bufor[0].buf[ bufor[0].koniec ] = tab[i] ; /* umieszczenie znaku w buforze */
/*wskaznik na koniec bufora iteruje i wypisuje napotkane znaki*/
++bufor[0].koniec;
printf("%c", tab[i]);
printf("\n");
/*sprawdza czy bufor pelen, jesli tak - ustawia wskaznik konca na 0*/
if(bufor[0].koniec == 32)
bufor[0].koniec = 0;
podnies(sem1); /* podniesienie semafora do odczytu */
}
}
/* przeslanie znaku ktory oznacza koniec pliku */
opusc(sem1) ;/* opuszczenie semafora do zapisu */
bufor[0].buf[ bufor[0].koniec ] = (char)(4);
++bufor[0].koniec ; /*iteruje do kkonca*/
/*sprawdza czy bufor pelen, jesli tak - ustawia wskaznik konca na 0*/
if( bufor[0].koniec == 32 )
bufor[0].koniec = 0;
/* podniesienie semafora do odczytu */
podnies(sem1) ;
fclose(zrodlo);
return 0;
}
/*producent*/
/*sterowanie*/
union semun {
int val; /*wartosc dla SETVAL*/
struct semid_ds *buf;/*buffer dla IPC_STAT / IPC_SET*/
unsigned short *array; /*tablica dla GETALL, SETALL*/
};
/*tworze semafor...*/
int StworzSemafor(key_t klucz){
int semid;/*ID zbioru semaforow*/
semid=semget(klucz,1,IPC_CREAT|IPC_EXCL|0666); /*tworze semafor dla klucza*/
return semid;
}
/*inicjalizacja*/
void przyp_wartosc(int semid){
union semun sterowanie;
sterowanie.val = 1;
semctl(semid,0,SETVAL,sterowanie); /*ustawienie Setval na 1*/
}
/*opuszczanie semafora*/
void opusc(int semid){
struct sembuf wykonaj={0,-1,0}; /*semnum(nr semafora),sem_op(operacja na semaforach),sem_flg (0-operacja nieblokujaca)*/
semop(semid, &wykonaj, 1);
}
/*podnies semafor*/
void podnies(int semid){
struct sembuf wykonaj = {0,1,0};
semop(semid, &wykonaj, 1);
}
/*usun semafor*/
void usun(int semid){
printf("semafory zostaly zwolnione\n");
semctl(semid,0,IPC_RMID);
}
/*kolejka procesow*/
int ilosc(int semid){
int kolejka;
kolejka = semctl(semid, 0, GETNCNT); /*odczytanie liczby procesów czekających wskutek wywołania operacji P(S)*/
return kolejka;
}
/*dostep*/
key_t dostepSem(){
key_t klucz;
klucz = ftok("./powielacz",getpid());
return klucz; }
/*tworze pamiec dzielona*/
int pamiecTworz(int id, int rozmiar){
key_t klucz=ftok(".",id); /*tworze klucz identyfikujacy dla pewnego obszaru pamieci*/
int id_pam=shmget(klucz, rozmiar, IPC_CREAT|0666); /*tworze segment pamieci o podanym rozmiarze*/
if(id_pam!=-1){ /*obsluga bledow*/
printf("pamiec o IDENTYFIKATORZE: %d\n",id_pam);
}
else perror("blad przy tworzeniu!\n");
return id_pam;
}
/*usuwam pamiec */
void usunPam(int id_pam){
struct shmid_ds buf; /*buf wskaznik do shmid_ds z sys/shm.h*/
if( shmctl(id_pam, IPC_RMID, (struct shmid_ds*)0) == -1 ) { /*odznaczam segment do usuniecia,; fizyczne usuniecie nastapi gdy nie bedzie on przylaczony do przestrzeni adresowej zadnego procesu + zastosowalem rzutowanie zeby typy sie zgadzaly*/
perror("Blad usuwania pamieci dzielonej\n") ;
exit(EXIT_FAILURE) ;
}
else printf("pamiec o ID %d usunieto!\n", id_pam);
}
/*uzyskuje dostep do pamieci i zwracam jej ID*/
int dostep(int id){
int id_pam;
id_pam=pamiecTworz(id,0); /*tu prawie to samo co w funkcji wyzej, gdyz shmget() tworzy i uzyskuje dostep do segmentu pamieci...*/
return id_pam;
}
/*tworze dowiazanie segmentu pamieci dzielonej i zwracam jego adres*/
void *dowiazanie(int id_pam){ /*funkcja potrzebna procesowi ktory chce skorzystac z pamieci dzielonej*/
if(shmat(id_pam,0,0)==(void*)-1){
perror("blad przy dowiazaniu segm. pamieci\n"); }
else{
printf("dowiazanie przebieglo pomyslnie!\n");
return shmat(id_pam,NULL,0); }
}
/*usuwam dowiazanie*/
void usunDow(void *id_pam){ /*gdy segment przestaje byc potrzebny w procesie, nalezy go odlaczyc*/
if(shmdt(id_pam)==-1){ /*usun*/
perror("nie mozna usunac dowiazania pamieci!\n");
}
else printf("usunalem dowiazanie pamieci\n");
}
/*rozmiar pamieci*/
int roz_miar(int id_pam){
struct shmid_ds x;
if(shmctl(id_pam,IPC_STAT,&x)==-1){
perror("nie mozna zwrocic rozmiaru pamieci!\n"); }
else return x.shm_segsz; /*zwraca rozmiar segmentu w bajtach*/
}