Witam, mam do napisania dwa programy, jeden z nich to pisarz, drugi to czytelnik. Pisarzy może być dwóch co czytelnik musi obsłużyć. Pisanie będzie się odbywać do jednej pamięci współdzielonej. Pisarze czytają z plików typu /etc/group, /etc/profile podawanych jako parametr przy uruchamianiu programu. Czytelnik odczytuje z pamięci napis i wyświetla ją na ekran oraz zapisuje do pliku odpowiadającego danemu pisarzowi. Wszystko ma być zsynchronizowane za pomocą semaforów. Poniżej wklejam kod obu programów, niestety nie wiem w jaki sposób sprawić, żeby działały one poprawnie.
pisarz.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#define NAZWA_PLIKU "pisarz.c"
#define ROZMIAR_PAMIECI 130
void podnies(int numer, int id);
void opusc(int numer, int id);
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "Niepoprawna liczba argumentow!\n");
exit(EXIT_FAILURE);
}
FILE *plikWejsciowy = fopen(argv[1], "r");
if (plikWejsciowy == NULL)
exit(EXIT_FAILURE);
key_t klucz = ftok(NAZWA_PLIKU, 'r');
if (klucz == -1)
exit(EXIT_FAILURE);
int idPamiec = shmget(klucz, ROZMIAR_PAMIECI * sizeof(char), 0666 | IPC_CREAT);
char *pamiec = (char *)shmat(idPamiec, NULL, 0);
int idSemafor = semget(IPC_PRIVATE, 2, 0666 | IPC_CREAT);
semctl(idSemafor, 0, SETVAL, 1);
semctl(idSemafor, 1, SETVAL, 0);
FILE *plikSemafor = fopen("semid1", "r");
if (plikSemafor == NULL)
{
plikSemafor = fopen("semid1", "w");
if (plikSemafor == NULL)
exit(EXIT_FAILURE);
fprintf(plikSemafor, "%d %d", idSemafor, getpid());
fclose(plikSemafor);
}
else
{
fclose(plikSemafor);
plikSemafor = fopen("semid2", "r");
if (plikSemafor == NULL)
{
plikSemafor = fopen("semid2", "w");
if (plikSemafor == NULL)
exit(EXIT_FAILURE);
fprintf(plikSemafor, "%d %d", idSemafor, getpid());
fclose(plikSemafor);
}
else
fclose(plikSemafor);
}
char linia[ROZMIAR_PAMIECI];
while (fgets(linia, ROZMIAR_PAMIECI, plikWejsciowy) != NULL)
{
opusc(0, idSemafor);
sprintf(pamiec, "%d %s", getpid(), linia);
puts(linia);
podnies(1, idSemafor);
}
opusc(0, idSemafor);
strcpy(pamiec, "koniec");
podnies(1, idSemafor);
shmdt(pamiec);
shmctl(idPamiec, IPC_RMID, NULL);
semctl(idSemafor, 0, IPC_RMID);
return 0;
}
void podnies(int numer, int id)
{
struct sembuf sem;
sem.sem_num = numer;
sem.sem_op = 1;
sem.sem_flg = 0;
semop(id, &sem, 1);
}
void opusc(int numer, int id)
{
struct sembuf sem;
sem.sem_num = numer;
sem.sem_op = -1;
sem.sem_flg = 0;
semop(id, &sem, 1);
}
czytelnik.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#define NAZWA_PLIKU "pisarz.c"
#define ROZMIAR_PAMIECI 130
void podnies(int numer, int id);
void opusc(int numer, int id);
int zwroc_pid(char *linia);
int main(void)
{
key_t klucz = ftok(NAZWA_PLIKU, 'r');
if (klucz == -1)
exit(EXIT_FAILURE);
int idPamiec = shmget(klucz, ROZMIAR_PAMIECI * sizeof(char), 0666 | IPC_CREAT);
char *pamiec = (char *)shmat(idPamiec, NULL, 0);
int idSemafor1, idSemafor2, pid1, pid2;
int czyCzytac1 = 1;
int czyCzytac2 = 0;
FILE *plikSemafor = fopen("semid1", "r");
if (plikSemafor == NULL)
exit(EXIT_FAILURE);
else
{
fscanf(plikSemafor, "%d %d", &idSemafor1, &pid1);
fclose(plikSemafor);
plikSemafor = fopen("semid2", "r");
if (plikSemafor == NULL)
{
idSemafor2 = -1;
pid2 = -1;
}
else
{
czyCzytac2 = 1;
fscanf(plikSemafor, "%d %d", &idSemafor2, &pid2);
fclose(plikSemafor);
}
}
FILE *plik1 = NULL;
FILE *plik2 = NULL;
plik1 = fopen("PLIK1", "w");
if (plik1 == NULL)
exit(EXIT_FAILURE);
if (idSemafor2 != -1)
{
plik2 = fopen("PLIK2", "w");
if (plik2 == NULL)
exit(EXIT_FAILURE);
}
int licznik1 = 0;
int licznik2 = 0;
while (1)
{
int pid = zwroc_pid(pamiec);
opusc(1, idSemafor1);
if (pid == pid1 && czyCzytac1 == 1)
{
if (strcmp(pamiec, "koniec") == 0)
czyCzytac1 = 0;
if (czyCzytac1 == 1)
{
fprintf(plik1, "%s", pamiec);
fprintf(stdout, "%s", pamiec);
licznik1++;
}
}
podnies(0, idSemafor1);
opusc(1, idSemafor2);
if (pid == pid2 && czyCzytac2 == 1)
{
if (strcmp(pamiec, "koniec") == 0)
czyCzytac2 = 0;
if (czyCzytac2 == 1)
{
fprintf(plik2, "%s", pamiec);
fprintf(stdout, "%s", pamiec);
licznik2++;
}
}
podnies(0, idSemafor2);
if (czyCzytac1 == 0 && czyCzytac2 == 0)
break;
usleep(100000);
}
printf("Do pliku PLIK1 zapisano %d linii.\n", licznik1);
fclose(plik1);
if (idSemafor2 != -1)
{
printf("Do pliku PLIK2 zapisano %d linii.\n", licznik2);
fclose(plik2);
}
return 0;
}
void podnies(int numer, int id)
{
struct sembuf sem;
sem.sem_num = numer;
sem.sem_op = 1;
sem.sem_flg = 0;
semop(id, &sem, 1);
}
void opusc(int numer, int id)
{
struct sembuf sem;
sem.sem_num = numer;
sem.sem_op = -1;
sem.sem_flg = 0;
semop(id, &sem, 1);
}
int zwroc_pid(char *linia)
{
char *pid = (char *)malloc(sizeof(char) * 10);
int i;
for(i = 0; linia[i] != ' '; i++)
pid[i] = linia[i];
pid[i] = '\0';
return atoi(pid);
}