moj program polega na tym ze 3 razy sobie forkuje tworzac 3 procesy o tym samym rodzicu. proces glowny tworzy 2 pamieci dzielone (jedna dla wczytanej linijki, druga dla zliczonej ilosci znakow). proces p1 zapisuje do pamieci dzielonej wczytana linijke, ale przedtym musi sprawdzic czy zostal opuszczony semafor.
problem jest gdzies tu:
proces p1 probuje opuscic semafor[0] i kiedy mu sie uda to przechodzi do wczytywania linijki:
while(opusc(semID, 0) != 0);
funkcja wyglada tak:
int opusc(int klucz, int nr){
semafor.sem_num=nr;
semafor.sem_op=-1;
semafor.sem_flg=0;
if(semop(klucz, &semafor, 1)==-1)
return 1;
return 0;
}
program wchodzi do funkcji opusc ale po wykonaniu funkcji semop
if(semop(klucz, &semafor, 1)==-1)
return 1;
program sie rozplywa i nie mam pojecia dlaczego, nawet nie wiem gdzie jestem.
probowalem cos z debuggerem ale na linuxie z forkami to srednio dziala
caly moj kod:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <signal.h>
#define KLUCZ_CHAR 256
#define ROZMIAR_CHAR 128
#define KLUCZ_INT (KLUCZ_CHAR + 1)
#define ROZMIAR_INT 4
#define KLUCZ_SEM 512
char wybor='0';
int sygnal, P1, P2, P3;
struct sembuf semafor;
int stop1 = 0, stop2 = 0, stop3 = 0;
int term1 = 0, term2 = 0, term3 = 0;
int podnies(int klucz, int nr){
semafor.sem_num=nr;
semafor.sem_op=1;
semafor.sem_flg=0;
if(semop(klucz, &semafor, 1)==-1)
return 1;
return 0;
}
int opusc(int klucz, int nr){
semafor.sem_num=nr;
semafor.sem_op=-1;
semafor.sem_flg=0;
if(semop(klucz, &semafor, 1)==-1)
return 1;
return 0;
}
void menu(){
printf("Menu\n");
printf("1. Wczytywanie z stdin\n");
printf("2. Wczytywanie z stdfile\n");
//printf("%c\n",wybor);
wybor=getchar();
printf("Wybrano: %c\n",wybor);
fflush(stdin);
}
int main(){
int pamiecDzielonaChar = shmget(KLUCZ_CHAR, ROZMIAR_CHAR, IPC_CREAT|0666);
char *bufferChar = (char*)shmat(pamiecDzielonaChar, NULL, 0);
int pamiecDzielonaInt = shmget(KLUCZ_INT, ROZMIAR_INT, IPC_CREAT|0666);
int *bufferInt = (int*)shmat(pamiecDzielonaInt, NULL, 0);
int semID = semget(KLUCZ_SEM, 3, IPC_CREAT|0666);
semctl(semID, 0, SETVAL, (int)1);
semctl(semID, 1, SETVAL, (int)0);
semctl(semID, 2, SETVAL, (int)0);
P1 = fork();
switch(P1)
{
//printf("jestem tutaj");
case 0://proces P1
while(!term1){
menu();
switch(wybor){
char nazwaPliku[80];
FILE *plik;
char tekst[ROZMIAR_CHAR];
case '1'://stdin
while(!stop1) {//i dopoki sem 0 jest
while(opusc(semID, 0) != 0);
fgets(tekst, ROZMIAR_CHAR, stdin);
if (tekst[0] == '.' && tekst[1] == '\n')
break;
strcpy(bufferChar, tekst);
podnies(semID, 1);
}
break;
case '2'://stdfile NIESKONCZONE
printf("Podaj nazwa pliku: ");
scanf("%s", nazwaPliku);
if ((plik = fopen(nazwaPliku, "rt")) == NULL) {
printf ("Nie mogę otworzyć pliku \"%s\" do zapisu!\n", nazwaPliku);
exit(1);
}
int i = 0;
tekst[i++] = getc(plik);
while(tekst[i - 1] != EOF){
tekst[i++] = getc(plik);
}
fclose(plik);
plik = NULL;
opusc(semID, 0);
strcpy(bufferChar, tekst);
podnies(semID, 1);
break;
}
}
exit(0);
break;
case -1:
printf("err\n");
exit(1);
break;
default:
switch(P2 = fork())
{
case 0://proces P2
while(!term2){
while(!stop2){
while(!opusc(semID, 0)){
opusc(semID, 1);
bufferInt[0] = strlen(bufferChar);
podnies(semID, 2);
}
}
}
break;
case -1:
printf("err\n");
exit(1);
break;
default:
switch(P3 = fork())
{
case 0://proces P3
printf("%d", getpid());
while(!term3){
while(!stop3){
while(!opusc(semID, 2)){
printf("%d", bufferInt[0]);
printf("Zapisalem do inta");
podnies(semID, 0);
}
}
}
break;
case -1:
printf("err\n");
exit(1);
break;
default:
break;
}
break;
}
break;
}
wait(NULL);
wait(NULL);
wait(NULL);
unlink("kolejka");
semctl(semID, 0, IPC_RMID);
semctl(semID, 1, IPC_RMID);
semctl(semID, 2, IPC_RMID);
shmdt(bufferChar);
shmdt(bufferInt);
shmctl(pamiecDzielonaChar, IPC_RMID, 0);
shmctl(pamiecDzielonaInt, IPC_RMID, 0);
return 0;
}