Nowe posty

Autor Wątek: Pamiec wspoldzielona, semafory  (Przeczytany 1614 razy)

Offline Jan Kowalski

  • Users
  • Nowy na forum
  • *
  • Wiadomości: 1
    • Zobacz profil
Pamiec wspoldzielona, semafory
« dnia: 2016-01-09, 13:05:03 »
Witam, pomoże mi ktoś poprawić program pracujący na semaforach i pamieci wspoldzielonej?

LOG script:

Script started on sob, 9 sty 2016, 13:00:42
]0;kamil@kamil-VirtualBox: ~/Pulpitkamil@kamil-VirtualBox:~/Pulpit$ gcc zad2.c -o zad2
zad2.c: In function ‘usunPam’:
zad2.c:181:17: error: storage size of ‘buf’ isn’t known
 struct shmid_ds buf; /*buf wskaznik do shmid_ds z sys/shm.h*/
                 ^
zad2.c: In function ‘dowiazanie’:
zad2.c:200:21: warning: comparison between pointer and integer [enabled by default]
 if(shmat(id_pam,0,0)==(void*)-1){
                     ^
zad2.c:204:10: warning: return makes pointer from integer without a cast [enabled by default]
          return shmat(id_pam,NULL,0); }
          ^
zad2.c: In function ‘roz_miar’:
zad2.c:218:17: error: storage size of ‘x’ isn’t known
 struct shmid_ds x;
                 ^
]0;kamil@kamil-VirtualBox: ~/Pulpitkamil@kamil-VirtualBox:~/Pulpit$ exit

Script done on sob, 9 sty 2016, 13:00:55


kod programu:
#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*/
}


 

Online Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 2538
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
    • keybase.io/pkraszewski
Odp: Pamiec wspoldzielona, semafory
« Odpowiedź #1 dnia: 2016-01-09, 16:08:09 »
Nie wiem, co program ma robić (a jestem zbyt speniewierany, żaby się wczytywać), ale:

W programie brakuje
#include <sys/shm.h>

Plik wejściowy
> cat plik.txt 
Hello from C


Kompilacja (warningi są rozsądne)
> gcc -Wall main.c -o zad2     
main.c: In function ‘usunPam’:
main.c:184:21: warning: unused variable ‘buf’ [-Wunused-variable]
     struct shmid_ds buf;                                            /*buf wskaznik do shmid_ds z sys/shm.h*/
                     ^
main.c: In function ‘dowiazanie’:
main.c:214:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
main.c: In function ‘roz_miar’:
main.c:234:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^

Wynik działania:
> ./zad2 
pamiec o IDENTYFIKATORZE: 2129955
pamiec o IDENTYFIKATORZE: 2129955
dowiazanie przebieglo pomyslnie!
H
e
l
l
o
 
f
r
o
m
 
C



Kompilator:
> gcc -v
Using built-in specs.
COLLECT_GCC=/usr/x86_64-pc-linux-gnu/gcc-bin/4.9.3/gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/4.9.3/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /var/tmp/portage/sys-devel/gcc-4.9.3/work/gcc-4.9.3/configure --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/4.9.3 --includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include --datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.9.3 --mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.9.3/man --infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/4.9.3/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4 --with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/4.9.3/python --enable-languages=c,c++,go,fortran --enable-obsolete --enable-secureplt --disable-werror --with-system-zlib --enable-nls --without-included-gettext --enable-checking=release --with-bugurl=https://bugs.gentoo.org/ --with-pkgversion='Gentoo 4.9.3 p1.3, pie-0.6.3' --enable-libstdcxx-time --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-multilib --with-multilib-list=m32,m64 --disable-altivec --disable-fixed-point --enable-targets=all --disable-libgcj --enable-libgomp --disable-libmudflap --disable-libssp --enable-libcilkrts --enable-lto --with-cloog --disable-isl-version-check --enable-libsanitizer
Thread model: posix
gcc version 4.9.3 (Gentoo 4.9.3 p1.3, pie-0.6.3)

Wynik jest taki sam także przy kompilowaniu GCC 5.3.0 i CLANG 3.7.0
« Ostatnia zmiana: 2016-01-09, 16:13:15 wysłana przez Paweł Kraszewski »
Paweł Kraszewski
~Gentoo/FreeBSD/OpenBSD/Specjalizowane customy