Komunikowanie się procesów za pomocą potoków

0

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.

0

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"

1

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.

0

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.

0

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.

  1. Z tego co pamiętam program posiada 2 mechanizmy komunikacji (potok, i plik)
  2. Synchronizacja na semaforach
  3. 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ść.
  4. 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); 
			}
	
	}
}

0
qq napisał(a)

z czasów studiów

Niech ktoś to zmieni na "z czasu studiów" :D

1

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;
}

 

1 użytkowników online, w tym zalogowanych: 0, gości: 1