Witam ponownie. Jestem w trakcie pisania programu związanego z problemem wzajemnego wykluczania. Niestety, mimo iż program został napisany wg algorytmu, który znalazłem, proces proces.x w ogóle nie wchodzi do sekcji krytycznej. Prosiłbym o podpowiedź, gdzie należy szukać błędu, co zostało napisane nie tak. Przyznaję, że średnio rozumiem temat semaforów. Poniżej zamieszczam kod:
powielacz.c - tworzy zadaną przez użytkownika liczbę procesów (drugi argument wywołania) w oparciu o nazwę pliku (pierwszy argument):
#include "func.h"
#define BASE 0 //trzeci argument funkcji strtol
#define PATH_SIZE 25 //maksymalna długość ścieżki
#define PN_WSK 2 //przesunięcie wskaźnika na tablicę path
#define FIRST_CHARS "./"
#define VAL 1
int main(int argc, char const *argv[])
{
if (argc<3) //liczba argumentow wywolania
{
perror("Zbyt mala liczba argumentow wywolania!\nProsze uruchomic program ponownie, z wlasciwa liczba arugmentow.\n");
exit(6);
}
const int syg_nr=strtol(argv[2], NULL, BASE); //liczba procesów
char path[PATH_SIZE]=FIRST_CHARS; //ścieżka poprzedzona znakami "./"
int key; //klucz
int id_sem; //ID zbioru
if(syg_nr==-1) //błędny pierwszy argument
{
perror("Blad funkcji strtol()\n");
exit(8);
}
if(syg_nr<=1) //błędny drugi argument
{
perror("Liczba procesow musi byc wieksza niż 1!\nProsze o ponowne uruchomienie programu z poprawnym parametrem.\n");
exit(6);
}
if(sscanf(argv[1], "%s", path+PN_WSK)==-1) //pierwszy argument
{
perror("Blad funkcji sscanf()\n");
exit(7);
}
key=semAccess(); //uzyskanie dostępu
id_sem=createSem(key); //utworzenie zbioru
setValue(id_sem, VAL); //przypisanie wartości
for(int i=1; i<=syg_nr; i++)
{
const int child_pid=fork();
if(child_pid==-1)
{
fprintf(stderr, "Nie udalo sie utworzyc procesu potomnego o numerze: %d.\n", i);
exit(9);
}
else if(child_pid==0)
{
if(execl(path, argv[1], NULL)==-1)
{
perror("Blad funkcji exec()\n");
exit(10);
}
}
sleep(4);
}
semDelete(id_sem);
return 0;
}
proces.c - program, który wrzucam do powielacza:
#include "func.h"
#define LOOP_TM 5 //liczba wejść do sekcji krytycznej
int main(int argc, char const *argv[])
{
key_t key; //klucz do zbioru semaforów
const int pid=getpid(); //ID procesu
int id_sem; //ID zbioru semaforów
key=semAccess(); //uzyskanie klucza do zbioru semaforów
id_sem=createSem(key); //utworzenie zbioru
for(int i=1; i<=LOOP_TM; i++)
{
down(id_sem);
printf("Proces o ID: %d uzyskal dostep do sekcji krytycznej po raz: %d\n", pid, i);
sleep(1);
printf("Proces o ID: %d opuszcza sekcje krytyczna po raz: %d\n", pid, i);
up(id_sem);
sleep(1);
printf("Proces o ID: %d przeszedl do sekcji reszty po raz: %d\n", pid, i);
}
//5-krotne przejście procesu do sekcji krytycznej
//oraz wyjście z niej
//zgodnie z algorytmem zamieszczonym w materiałach
printf("Proces %d opuscil petle...\n", pid); //komunikat końcowy procesu
return 0;
}
func.c:
#include "func.h"
#define SEM_NR 1 //liczba semaforów
#define MODE 0666 //tryb
#define SEM0 0 //nr semafora w zbiorze
#define PATH "./proces.x" //ścieżka pliku dla funkcji ftok()
int createSem(key_t key)
{
int semid;
semid=semget(key, SEM_NR, IPC_CREAT|IPC_EXCL|MODE);
//if(==-1);
//{
// perror("Blad funkcji createSem()\n");
//exit(4);
//}
return semid;
}
void setValue(int semid, int val)
{
union semun ctrl;
ctrl.val=val;
if(semctl(semid, SEM0, SETVAL, ctrl)==-1) //SETVAL orzymuje wartość 1
{
perror("Blad funkcji setValue()\n");
exit(5);
}
}
void up(int semid)
{
struct sembuf do_op = {0, 1, 0};
//struktura zawiera kolejno: nr semafora, operację, flagę
//czyli: semnum, sem_op, sem_flg
//0 - operacja blokująca
if(semop(semid, &do_op, SEM_NR)==-1)
{
perror("Blad funkcji up()\n");
exit(2);
}
}
void down(int semid)
{
struct sembuf do_op = {0, -1, 0};
if(semop(semid, &do_op, SEM_NR)==-1)
{
perror("Blad funkcji down()\n");
exit(2);
}
}
void semDelete(int semid) //usuwanie semafora
{
if(semctl(semid, SEM0, IPC_RMID)==-1) //obsługa błędów
{
perror("Blad funkcji semDelete\n");
exit(1);
}
else //komunikat
{
printf("Semafor zostal usuniety\n");
}
}
key_t semAccess() //uzyskanie dostępu do semafora
{
int key;
if((key=ftok(PATH, getpid()))==-1)
{
perror("Blad funkcji semAccess()\n");
exit(3);
}
return key;
}
func.h:
#ifndef FUNC_H
#define FUNC_H
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#ifdef _SEM_SEMUN_UNDEFINED
union semun {
int val; //wartosc dla SETVAL
struct semid_ds *buf; //bufor dla IPC_STAT, IPC_SET
unsigned short *array; //tablica dla GETALL, SETALL
struct seminfo *__buf; //bufor dla IPC_INFO (specyfika Linuksa)
};
#endif //_SEM_SEMUN_UNDEFINED
int createSem(key_t key); //utworzenie semafora
void setValue(int semid, int val); //przypisanie wartośći (inicjalizacja)
void up(int semid); //podniesienie semafora...
void down(int semid); //...i jego opuszczenie
key_t semAccess(); //dostęp do semafora
//int queue(int semid); //kolejka
void semDelete(int semid); //usunięcie semafora
#endif //FUNC_H
W func.c funkcja createSem() miała mieć obsługę błędów, ale gdy ją dodaję, kompilator ostrzega o warunku, który nie chroni, a program zwraca błąd: "Blad funkcji createSem(): Success".