main() { int semid = -1; // identyfikator semafora int co; int jeszcze; if ((semid = semget(ftok("/tmp",0), 1, IPC_CREAT | PERMS)) < 0) perror("blad tworzenia semafora"); printf("Podaj Polecenie\n 1 - podnies semafor\n 2 - opusc semafor\n 0 - wyjscie\n"); for (jeszcze = 1;jeszcze;) { scanf("%d",&co); printf("wybrano %d\n",co); switch(co) { case 2: { printf("przed blokuj\n"); blokuj(semid); printf("po blokuj\n"); break; } case 1: { printf("przed odblokuj\n"); odblokuj(semid); printf("po odblokuj\n"); break; } case 0: { jeszcze = 0; break; } default: { printf("nie rozpoznana komenda %d\n",co); } } } } Co się dzieje gdy wykonamy operacje V (podniesienie) za pierwszym razem? Co się stanie gdy wykonamy operacje V za drugim razem? Ile razy możemy teraz wykonać operację P (opuszczenie)? Otworzyć drugą konsolę i uruchomić nasz program, podnieść semafor, co się stało na pierwszym terminalu? Opuścić semafor w pierwszym terminalu, co się stało? Otworzyć trzeci terminal i podnieść semafor, czy na obu terminalach doszło do odblokowania? Na trzecim terminalu jeszcze raz podnieść semafor Gdy wszystkie terminale odblokowane wyjść przez 0. Komendą ipcs sprawdzić czy semafor został w systemie. Komendą ipcrm -s usunąć semafor z systemu zmodyfikować tablicę operacji tak by operacja opuszczenia semafora była nie blokująca (IPC_NOWAIT) Uruchomić program i spróbować opuścić semafor podnieść go po czym znowu opuścić. WYjść i usunąć semafor Uruchomić program podnieść kilka razy semafor i wyjść (nawet przez ^C) Nie usuwać semafora, uruchomić program jeszcze raz tym razem próbując opuścić semafor. Czy stan semafora został zapamiętany? Wprowadzić modyfikacje do tablic operacji polegającą na dodaniu opcji SEM_UNDO Usunąć semafor, skompilować i uruchomić program. Powtórnie podnieść kilka razy semafor i wyjść uruchomić i spróbować opuścić semafor. Czy udało nam się zapamiętać ten stan? W powyższym przykładzie nowo zainicjowany semafor był zawsze opuszczony. Możemy zrealizować semafor na odwrót (powinien czekać aż będzie 0 i operacja P będzie zwiększać wartość semafora natomiast operacja V znmiejszać). static struct sembuf op_lock[2] = { 0,0,0, /* czekaj, aż semafor nr 0 stanie się zerem */ 0,1,0 /* następnie zwiększ ten semafor 1*/ };
static struct sembuf op_unlock[1] = { 0, -1, IPC_NOWAIT /* zmniejsz semafor nr 0 o 1 bez czekania bo to zwolnienie zasobów */ }; Spróbować wykonać operacje blokowania i odblokowywania za pomocą nowych operacji Napisać "programik" usuwający semafor. MOZE SIE CI PRZYDA A JAK NIE TO ADMIN ZABIERZE PUNKTY ;P
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define PERMS 0666
static struct sembuf op_lock[1] = {
0, -1, 0
};
static struct sembuf op_unlock[1] = {
0, 1, 0
};
void blokuj(int semid)
{
if (semop(semid, &op_lock[0], 1)<0)
perror("blad lokowania semafora");
}
void odblokuj(int semid)
{
if (semop(semid, &op_unlock[0], 1) < 0)
perror("blad odlokowania semafora");
}
main()
{
int semid = -1; // identyfikator semafora
int co;
int jeszcze;
if ((semid = semget(ftok("/tmp",0), 1, IPC_CREAT | PERMS)) < 0)
perror("blad tworzenia semafora");
printf("Podaj Polecenie\n 1 - podnies semafor\n 2 - opusc semafor\n 0 - wyjscie\n");
for (jeszcze = 1;jeszcze;)
{
scanf("%d",&co);
printf("wybrano %d\n",co);
switch(co)
{
case 2:
{
printf("przed blokuj\n");
blokuj(semid);
printf("po blokuj\n");
break;
}
case 1:
{
printf("przed odblokuj\n");
odblokuj(semid);
printf("po odblokuj\n");
break;
}
case 0:
{
jeszcze = 0;
break;
}
default:
{
printf("nie rozpoznana komenda %d\n",co);
}
}
}
} Co się dzieje gdy wykonamy operacje V (podniesienie) za pierwszym razem? Co się stanie gdy wykonamy operacje V za drugim razem? Ile razy możemy teraz wykonać operację P (opuszczenie)? Otworzyć drugą konsolę i uruchomić nasz program, podnieść semafor, co się stało na pierwszym terminalu? Opuścić semafor w pierwszym terminalu, co się stało? Otworzyć trzeci terminal i podnieść semafor, czy na obu terminalach doszło do odblokowania? Na trzecim terminalu jeszcze raz podnieść semafor Gdy wszystkie terminale odblokowane wyjść przez 0. Komendą ipcs sprawdzić czy semafor został w systemie. Komendą ipcrm -s usunąć semafor z systemu zmodyfikować tablicę operacji tak by operacja opuszczenia semafora była nie blokująca (IPC_NOWAIT) Uruchomić program i spróbować opuścić semafor podnieść go po czym znowu opuścić. WYjść i usunąć semafor Uruchomić program podnieść kilka razy semafor i wyjść (nawet przez ^C) Nie usuwać semafora, uruchomić program jeszcze raz tym razem próbując opuścić semafor. Czy stan semafora został zapamiętany? Wprowadzić modyfikacje do tablic operacji polegającą na dodaniu opcji SEM_UNDO Usunąć semafor, skompilować i uruchomić program. Powtórnie podnieść kilka razy semafor i wyjść uruchomić i spróbować opuścić semafor. Czy udało nam się zapamiętać ten stan?
W powyższym przykładzie nowo zainicjowany semafor był zawsze opuszczony. Możemy zrealizować semafor na odwrót (powinien czekać aż będzie 0 i operacja P będzie zwiększać wartość semafora natomiast operacja V znmiejszać). static struct sembuf op_lock[2] = {
0,0,0, /* czekaj, aż semafor nr 0 stanie się zerem */
0,1,0 /* następnie zwiększ ten semafor 1*/
};
static struct sembuf op_unlock[1] = {
0, -1, IPC_NOWAIT /* zmniejsz semafor nr 0 o 1 bez czekania bo to zwolnienie zasobów */
}; Spróbować wykonać operacje blokowania i odblokowywania za pomocą nowych operacji Napisać "programik" usuwający semafor. MOZE SIE CI PRZYDA A JAK NIE TO ADMIN ZABIERZE PUNKTY ;P