Mam napisać program który ma komunikować się między sobą za pomocą potoków nazwanych. W ogóle nie mam pojęcia jak to ugryźć. Mam to zrobić w ANSI C. Ale jeśli ktoś napisze jak to zrobić w C++ to też będzie mi bardzo pomocne. Rozwiązanie musi działać na windowsie i linuxie.
No ale czego oczekujesz? Że ktoś to napisze za ciebie? Bo nie uwierzę że w ogóle próbowaleś poszukać czego na ten temat, bo źródeł na ten temat jest z milion. Pierwsze z brzegu:
Stevens - "Advanced Programming In The UNIX Environment", rozdział 15 (przynajmniej w tej wersji którą mam) czyli "Interprocess Communication"
Masz linka:
Są tam potoki opisane.
http://sequoia.ict.pwr.wroc.pl/~witold/opsys/os_proc_s.pdf
Myślę, że mój wykładowca nie będzie miał mi tego za złe.
Jeżeli rozwiązanie ma działać zarówno na windowsie oraz na linuxie to zadanie jest 3 razy trudniejsze, niż mogło by się wydawać na pierwszy rzut oka.
Nie korzystałem z potoków pod WIN, więc Ci z tym nie pomogę niestety, tu masz kilka linków które mogą pomóc przy pisaniu kodu pod WIN.
http://msdn.microsoft.com/en-us/library/aa365781(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365780(v=vs.85).aspx
Powodzenia.
Znalazłem jakiś stary program, z czasów studiów, typu producent - konsument. Nie gwarantuję, że kod działa, bo nie wiem czy to jest wersja ostateczna, która oddałem na zaliczenie laboratorium.
- Z tego co pamiętam program posiada 2 mechanizmy komunikacji (potok, i plik)
- Synchronizacja na semaforach
- 3 procesy, 1 proces pobiera ze standardowego wejścia dane zamienia na heksy przesyła do procesu nr 2, proces nr 2 zamienia na dziesiętne - przesyła do procesu nr 3, proces nr 3 wypisuje wartość.
- Program działa pod linuksem
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#define SHM_SIZE 1024
#define N 10
#define FIFO_FILE "MOJEFIFO"
int main(void){
if(fork() == 0){
//printf("nadawca\n");
int shmid = shmget(0x123, sizeof(int)*N, 0666 | IPC_CREAT);/* systemowy identyfikator bloku pamięci dzielonej */
int semid = semget(0x234, 2, 0666 | IPC_CREAT); /* systemowy identyfikator semafora */
int *data; /* wskaźnik na tablicę z danymi */
int pos = 0; /* pozycja w tablicy */
struct sembuf op; /* struktura dla operacji na semaforze */
data = (int*)shmat(shmid, 0, 0);
/* ustawienie wartości początkowych semaforów */
semctl(semid, 0, SETVAL, N);
semctl(semid, 1, SETVAL, 0);
op.sem_flg = 0;
int i;
for(i = 0; i < 10; i++)
{
/* opuszczenie semafora producenta */
op.sem_num = 0;
op.sem_op = -1;
semop(semid, &op, 1);
/* zapis elementu do tablicy */
fscanf(stdin, "%d", &data[pos]);
printf("proces nr 1: zapisałem %d na pozycji %d\n", data[pos], pos);
pos = (pos + 1) % N;
/* podniesienie semafora konsumenta */
op.sem_num = 1;
op.sem_op = 1;
semop(semid, &op, 1);
}
}
else
if(fork() == 0){
int shmid = shmget(0x123, sizeof(int)*N, 0666 | IPC_CREAT);/* systemowy identyfikator bloku pamięci dzielonej */
int semid = semget(0x234, 2, 0666);/* systemowy identyfikator semafora */
int *data; /* wskaźnik na tablicę z danymi */
int pos = 0; /* pozycja w tablicy */
struct sembuf op; /* struktura dla operacji na semaforze */
char *tablica[10];
char buffer1[20];
char buffer2[20];
char buffer3[20];
char buffer4[20];
char buffer5[20];
char buffer6[20];
char buffer7[20];
char buffer8[20];
char buffer9[20];
char buffer10[20];
tablica[0] = buffer1;
tablica[1] = buffer2;
tablica[2] = buffer3;
tablica[3] = buffer4;
tablica[4] = buffer5;
tablica[5] = buffer6;
tablica[6] = buffer7;
tablica[7] = buffer8;
tablica[8] = buffer9;
tablica[9] = buffer10;
data = (int*)shmat(shmid, 0, 0);
op.sem_flg = 0;
/* opuszczenie semafora konsumenta */
op.sem_num = 1;
op.sem_op = -1;
semop(semid, &op, 1);
int i;
for(i = 0;i < 10; i++)
{
/* odczyt elementu z tablicy */
sprintf(tablica[i], "%xh", data[pos]);
printf("proces nr 2: odczytałem %d z pozycji %d, po przekonwertowaniu %s\n", data[pos], pos, tablica[i]);
pos = (pos + 1) % N;
}
/* podniesienie semafora producenta */
op.sem_num = 0;
op.sem_op = 1;
semop(semid, &op, 1);
FILE *fp = fopen(FIFO_FILE, "w");
fputs(tablica[i], fp);
fclose(fp);
//int fifo;
//char FIFO_FILE[9] = "ble.fifo";
//mkfifo(FIFO_FILE, 0777);
//fifo = open(FIFO_FILE, O_WRONLY);
//write(fifo, buffer, 20);
//fflush(FIFO_FILE);
//close(fifo);
//sleep(30); /* zeby nie skasowac pliku w trakcie czytania */
//unlink(FIFO_FILE);
}
else
if(fork() == 0)
{
char buffer2[20];
//int fifo;
//char FIFO_FILE[9] = "ble.fifo";
//mkfifo(FIFO_FILE, 0777);
//fifo = open(FIFO_FILE, O_RDONLY);
//read(fifo, buffer, 20);
//close(fifo);
//sleep(2); /* zeby nie skasowac pliku w trakcie czytania */
//unlink(FIFO_FILE);
// FILE *fp;
/* Tworzymy FIFO jeżeli nie istnieje */
umask(0);
mknod(FIFO_FILE, S_IFIFO|0666, 0);
FILE *fp = fopen(FIFO_FILE, "r");
fgets(buffer2, 20, fp);
printf("Otrzymany łańcuch: %s\n", buffer2);
int i;
for(i = 0; i < 10; i++)
{
printf("proces nr 3: odczytałem %s\n", buffer2);
//sprintf("%s\n", buffer);
}
}
}
qq napisał(a)
z czasów studiów
Niech ktoś to zmieni na "z czasu studiów" :D
Tu chyba ostateczna wersja.
/*
* kill -SIGUSR1 PID --->ZATRZYMANIE PROCESÓW
* kill -SIGCONT PID --->WZNOWIENIE WYKONYWANIA PROCESÓW
* kill -SIGUSR2 PID --->ZABIECIE PROCESÓW
################################
############################# */
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
int running = 1;
//############################################################
//DEFINIUJEMY FUNKCJE DO WYKONANIA PO PRZECHWYCENIU SYGNAŁOW##
//############################################################
void STOP(int signal)
{
if (running == 1)
{
// fprintf(stdout,"ZATRZYMANIE!!!\n");
running = 0;
kill(0,SIGUSR1);
}
}
void RUN(int signal)
{
if (running == 0)
{
// fprintf(stdout,"WZNOWIENIE!!!\n");
running = 1;
kill(0,SIGCONT);
}
}
void KILL(int signal)
{
fprintf(stdout,"ZAMORDOWALES MNIE!!!\n");
kill(0,SIGKILL);
}
//#############################################################
//ZACZYNAMY####################################################
//#############################################################
int main(void)
{
//#############################################################
//DEKLARUJEMY W MAMIE --> KAZDY Z PROCESÓW POTOMNYCH ZAWEIRA ##
//KOPIE TYCH FUNKCJI ##
//#############################################################
signal(SIGUSR1, STOP);
signal(SIGCONT, RUN);
signal(SIGUSR2, KILL);
//#############################################################
//TWORZYMY SEMAFORY ORAZ WYPEŁNIAMY JEGO STRUKTURĘ ##
//#############################################################
int semid = semget(354, 3, 0666 | IPC_CREAT);
struct sembuf semafor;
semctl(semid, 0, SETVAL, 1);
semctl(semid, 1, SETVAL, 0);
semctl(semid, 2, SETVAL, 0);
semafor.sem_flg = 0;
//#############################################################
//TWORZYMY 1 PROCES POTOMNY ##
//#############################################################
if (fork() == 0)//PROCES 1
{
//#############################################################
//TWORZYMY PAMIEĆ WSPÓŁDZIELONĄ ORAZ PODPINAMY POD NIĄ ZMIENNĄ#
//#############################################################
int shmid = shmget(234, sizeof(int), 0666 | IPC_CREAT);
int *liczba = (int*) shmat(shmid, 0, 0);
char litera;
for(;;)
{
//#############################################################
//PAUZA/WZNOWIENIE ##
//#############################################################
switch (running)
{
case 1 :
//############################################################
//OPUSZCZAMY SEMAFOR PROCESU 1 I PZRECHODZIMY DALEJ ##
//############################################################
semafor.sem_num = 0;
semafor.sem_op = -1;
semop(semid, &semafor, 1);
semafor.sem_flg = 0;
//###########################################################
//UPEWNIAMY SIE CZY SEMAFORY SA WYZEROWANE ##
//###########################################################
semctl(semid, 0, SETVAL, 0);
semctl(semid, 1, SETVAL, 0);
semctl(semid, 2, SETVAL, 0);
//############################################################
//POBIERAMY ZMIENNĄ TYPU CHAR ZE STANDARDOWEGO WEJŚCIA I ##
//ZAPISUJEMY POD ZMIENNĄ LITERA ##
//############################################################
fscanf(stdin, "%c", &litera);
//############################################################
//KONWERTUJEMY ZE ZMIENNEJ CHAR NA INT ##
//############################################################
*liczba = (int) litera;
fprintf(stdout, "PROCES 1 PISZE : %d\n", *liczba);
//############################################################
//PODNOSIMY SEMAFOR PROCESU 2 ##
//############################################################
semafor.sem_num = 1;
semafor.sem_op = 1;
semop(semid, &semafor, 1);
break;
case 0 :
break;
}
};
}
//#############################################################
//TWORZYMY 2 PROCES POTOMNY####################################
//#############################################################
if (fork() == 0)//PROCES 2
{
//#############################################################
//PODPINAMY SIĘ POD PAMIEĆ WSPÓŁDZIELONĄ #
//#############################################################
int shmid = shmget(234, sizeof(int), 0666 | IPC_CREAT);
int *litera = (int*) shmat(shmid, 0, 0);
//#############################################################
//TWORZYMY FIFO #
//#############################################################
mkfifo("ble.fifo", S_IFIFO|0777);
int fifo = open("ble.fifo", O_WRONLY);
char hex[256];
do{
switch (running)
{
case 1 :
//#############################################################
//KONWERSJA NA HEXY ZNAKU POBRANEGO W PIERWSZYM PROCESIE I ##
//ZAPIS DO TABLICY TYPU CHAR ##
//#############################################################
sprintf(hex, "%xh", *litera);
semafor.sem_num = 1;
semafor.sem_op = -1;
semop(semid, &semafor, 1);
semafor.sem_flg = 0;
semctl(semid, 0, SETVAL, 0);
semctl(semid, 1, SETVAL, 0);
semctl(semid, 2, SETVAL, 0);
//#############################################################
//KONWERSJA NA HEXY I ZAPIS DO TABLICY CHAR #
//#############################################################
write(fifo, &hex, sizeof(char)*256);
fprintf(stdout,"PROCES 2 PRZESYLA: %s \n", hex);
semafor.sem_num = 2;
semafor.sem_op = 1;
semop(semid, &semafor, 1);
break;
case 0 :
break;
}
}while(1);
}
//#############################################################
//TWORZYMY 3 PROCES POTOMNY####################################
//#############################################################
if (fork() == 0)//PROCES 3
{
//#############################################################
//PODPINAMY SIĘ POD FIFO #
//#############################################################
int fifo = open("ble.fifo", O_RDONLY);
char hex1[256];
do{
switch (running)
{
case 1 :
semafor.sem_num = 2;
semafor.sem_op = -1;
semop(semid, &semafor, 1);
semafor.sem_flg = 0;
semctl(semid, 0, SETVAL, 0);
semctl(semid, 1, SETVAL, 0);
semctl(semid, 2, SETVAL, 0);
//#############################################################
//ODCZYTUJEMY Z FIFO #
//#############################################################
read(fifo, &hex1, sizeof(char)*256);
fprintf(stdout,"PROCES 3 ODBIERA: %s \n\n", hex1);
semafor.sem_num = 0;
semafor.sem_op = 1;
semop(semid, &semafor, 1);
break;
case 0 :
break;
}
}while(1);
}
return 0;
}