Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lr5.doc
Скачиваний:
1
Добавлен:
08.11.2019
Размер:
70.66 Кб
Скачать

3.4 Системный вызов fdopen

Если

4 Пример программы

Слово состояния устройства в системе ввода-вывода представляется в виде:

№ разряда

15

14

13

12

11

10

09

08

07

06

05

04

03

02

01

00

Значение

C

C

C

C

C

0

F

B

N

N

N

N

N

N

N

N

где: C..C - код состояния

F - признак ошибки (1/0)

B - признак занятости (0/1)

N..N - количество байт, переданных в последней операции.

Для примера разработаны две программы. Программа lr5 запрашивает у пользователя неупакованные части слова состояния устройства и упаковывает их, используя самостоятельную программу упаковки, запущенную в отдельном процессе. Два процесса взаимодействуют через программный канал.

Пара программ lr5 и pack представляют собой пример программной реализации модели клиент-сервер. В программе-сервере pack реализован сервис: упаковка слова состояния. В программе lr5 реализован пользовательский интерфейс. Эта программа использует сервис, который реализован в pack, поэтому lr5 называют клиентом программы pack.

5 Контрольные вопросы

1. Что такое процесс? Что такое идентификационный номер процесса? Какие команды ОС Linux позволяют получить сведения о том, какие процессы сейчас запущены?

2. Как осуществляется запуск нового процесса? Как работает системный вызов fork()? Для чего служит системный вызов exec()?

3. С помощью какого системного вызова можно завершить работу процесса?

4. Что такое программный канал? Как организовать передачу данных от одного процесса другому через канал?

5. Что такое дескриптор файла? С помощью каких системных вызовов можно организовать запись в файл, чтение из файла? Какие возможны ошибочные ситуации при использовании этих системных вызовов?

6. Что такое системный вызов?

7. Каково назначение системного вызова dup(), dup2()?

Приложение А Текст программы-клиента

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#define oops(m,x) {perror(m); exit(x);}

int run_pack(int *, int *);

int run_ui(int *, int *);

int main(void)

{

int pid;

int to_pack[2], from_pack[2];

/*образовать два канала*/

if(pipe(to_pack) == -1 || pipe(from_pack) == -1)

{

oops("pipe failed", 1);

}

/*создать два процесса*/

switch(fork())

{

case -1:

oops("ошибка fork",1);

break;

case 0:

printf("Порожденный процесс pid=%d\n",getpid());

run_pack(to_pack,from_pack);

default:

printf("Родительский процесс pid=%d\n",getpid());

run_ui(to_pack, from_pack);

wait(NULL);

}

}

int run_pack(int in[2], int out [2])

{

if(dup2(in[0],0) == -1) /*дублирование дескриптора конца для чтения в дескриптор 0*/

{

oops("dc: cannot redirect stdin",3);

}

close(in[0]); /*уже продублировали in[0] в 0, будем читать данные через дескриптор 0*/

close(in[1]); /*закрываем записываемый конец канала*/

if(dup2(out[1],1) == -1) /*дублирование дескриптора конца для записи в дескриптор 1*/

{

oops("run_pack: cannot redirect stdout",4);

}

close(out[1]); /*уже продублировали out[1] в 1, будем записывать данные через дескриптор 1*/

close(out[0]); /*закрываем читаемый конец канала*/

execlp("./pack","./pack", NULL);

oops("cannot run pack",5);

}

int run_ui(int to_pack[2], int from_pack[2])

{

unsigned short c; /* код состояния */

unsigned short f; /* признак ошибки */

unsigned short b; /* признак занятости */

unsigned short n; /* количество байт */

unsigned short UnitStateWord; /*слово состояния */

FILE *fin, *fout;

int i;

close(to_pack[0]); /*не производить чтение из канала к pack*/

close(from_pack[1]); /*не записывать в канал из pack*/

fout = fdopen(to_pack[1],"w"); /*преобразовать файловые дескрипторы*/

fin = fdopen(from_pack[0],"r"); /*в потоки*/

if (fout == NULL || fin == NULL)

{

fprintf(stderr, "Ошибка: не удалось преобразовать каналы в потоки");

exit(1);

}

for (i =0; i<5; i++)

{

printf("Введите код состояния (0 - 31) >");

scanf("%hd",&c);

printf("Введите признак ошибки (0 / 1) >");

scanf("%hd",&f);

printf("Введите признак занятости (0 / 1) >");

scanf("%hd",&b);

printf("Введите кол-во переданных байт (0 - 255) >");

scanf("%hd",&n);

if (fprintf(fout, "%hd %hd %hd %hd\n", c,f,b,n) == EOF)

{

fprintf(stderr, "Ошибка: не удалось записать в канал");

exit(1);

}

fflush(fout);

if (fscanf(fin, "%hd",&UnitStateWord) <= 0)

{

break;

}

printf("Запакованое слово %hd\n", UnitStateWord);

}

fclose(fout);

fclose(fin);

}

Приложение Б. Текст программы-клиента

#include <stdio.h>

int main(void)

{

unsigned short c; /* код состояния */

unsigned short f; /* признак ошибки */

unsigned short b; /* признак занятости */

unsigned short n; /* количество байт */

unsigned short UnitStateWord; /*слово состояния */

/* формирование упакованного кода */

while (scanf("%hd%hd%hd%hd",&c,&f,&b,&n) != EOF)

{

/*fprintf(stderr,"pack schital %hd %hd %hd %hd \n", c,f,b,n);*/

UnitStateWord=((unsigned short int)c&0x1F)<<11;

UnitStateWord|=((unsigned short int)f&1)<<9;

UnitStateWord|=((unsigned short int)b&1)<<8;

UnitStateWord|=n&0xFF;

/* вывод результата */

printf("%hd\n", UnitStateWord);

fflush(stdout);

/*fprintf(stderr,"pack vivel %hd \n",UnitStateWord);*/

}

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]