Есть ещё один вид взаимодействия процессов в unix, каналы.
Рассмотрим на примере как это работает.
Программа parent создает канал с помощью системного вызова pipe(), далее приводит дескрипторы чтения и записи к символьному типу, создает форков(новый процесс, выполняющий ту же самую программу, у потомков fork() возвращает 0), форки вызывают программы src и dst, передавая им дескрипторы записи и чтения соответственно, джёт завершения форков и завершается сама. Программа src передает сообщение с помощью write(), используя дескриптор для записи в канал, который передан ей как аргумент и завершается. Программа dst получает сообщение с помощью read() и выводит его на экран, используя write(). Листинги программ:
Рассмотрим на примере как это работает.
Программа parent создает канал с помощью системного вызова pipe(), далее приводит дескрипторы чтения и записи к символьному типу, создает форков(новый процесс, выполняющий ту же самую программу, у потомков fork() возвращает 0), форки вызывают программы src и dst, передавая им дескрипторы записи и чтения соответственно, джёт завершения форков и завершается сама. Программа src передает сообщение с помощью write(), используя дескриптор для записи в канал, который передан ей как аргумент и завершается. Программа dst получает сообщение с помощью read() и выводит его на экран, используя write(). Листинги программ:
/*Файл parent.c: порождает двух форков, ждет их завершения, закрывает канал и завершается*/
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#define STR_SIZE 32
int
main(void)
{
int pf[2];
int pid1, pid2;
char spf[2][STR_SIZE];
/*Создание канала. Чтение идет через pf[0], запись - через pf[1]*/
if(pipe(pf) == -1){
fprintf(stderr, "pipe() error\n");
return 1;
}
/*Запись дескрипторов для последующей передачи в качестве параметров программам, осуществляющим запись и чтение*/
sprintf(spf[0], "%d", pf[0]);
sprintf(spf[1], "%d", pf[1]);
/*Первый форк вызывает программу src. В качестве параметра передается дескриптор для записи*/
if((pid1 = fork()) == 0){
close(pf[0]);
execl("./src", "src",
spf[1], NULL);
fprintf(stderr, "exec() [src] error\n");
return 1;
}
/*Второй форк вызывает программу dst. В качестве параметра передается дескриптор для чтения*/
if((pid2 = fork()) == 0){
close(pf[1]);
execl("./dst", "dst",
spf[0], NULL);
fprintf(stderr, "exec() [dst] error\n");
return 1;
}
/*Ждем и завершаемся*/
waitpid(pid1, NULL, 0);
close(pf[0]);
close(pf[1]);
waitpid(pid2, NULL, 0);
return 0;
}
/*Листинг src.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define PP_MESSAGE "Hello World\n"
#define WAIT_SECS 5
int
main(int argc, char ** argv)
{
int i, fd;
if(argc < 2){
fprintf(stderr, "src: Too few arguments\n");
return 1;
}
fd = atoi(argv[1]);
fprintf(stderr, "Wait please");
for(i = 0; i < WAIT_SECS; i++, sleep (1))
fprintf(stderr, ".");
fprintf(stderr, "\n");
if(write (fd, PP_MESSAGE,
strlen(PP_MESSAGE)) == -1){
fprintf(stderr, "src: write() error\n");
return 1;
}
close(fd);
return 0;
}
/*Листинг dst,c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int
main(int argc, char ** argv)
{
int fd;
char ch;
if(argc < 2){
fprintf(stderr, "dst: Too few arguments\n");
return 1;
}
fd = atoi(argv[1]);
while(read(fd, &ch, 1) > 0)
write(1, &ch, 1);
close(fd);
return 0;
}
Вот что получается в результате наших махинаций:![]() |
| Системный вызов pipe() |

Комментариев нет:
Отправить комментарий