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

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

№ разряда                                
Значение C C C C C   F B N N N N N N N N

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

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

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

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

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

При вызове программы в командной строке нужно указать количество генерируемых наборов чисел.

Текст программы приведен в приложении.

Пример работы программы:

$./lr41 2

Родительский процесс pid=4762

Порожденный процесс pid=4763

набор отправлен в канал

набор принят из канала

Код состояния = 2

Признак ошибки = 1

Признак занятости = 0

Количество переданных байт = 253

набор отправлен в канал

набор принят из канала

Код состояния = 25

Признак ошибки = 0

Признак занятости = 0

Количество переданных байт = 176

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

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

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

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

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

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

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

7. Каково назначение параметров функции main?

Приложение А

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#include <unistd.h>

#include <fcntl.h>

void reader (int); /* функциячтениянаборачиселизканала */

void generator (int, int); /* функциягенерации и записинаборачисел в канал */

void myerror (char *); /* функцияобработкиошибоксистемныхвызовов */

int main (int argc, char * argv [])

{

if (argc!= 2)

{

printf (" вызов: %s количество_наборов_чисел \n", argv [0]);

exit (1);

}

Else

{

int pipefd [2]; /* массивдескрипторовпрограммногоканала */

if (pipe (pipefd) == -1)

myerror (" ошибкасозданияканала ");

switch (fork ())

{

case -1:

myerror (" ошибка fork");

break;

case 0:

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

close (pipefd [0]);

generator (pipefd [1], atoi (argv [1]));

close (pipefd [1]);

break;

default:

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

close (pipefd [1]);

reader (pipefd [0]);

close (pipefd [0]);

break;

}

}

return 0;

}

void generator (int fd, int n)

/* функциягенерациинабораслучайныхчиселнужныхдиапазонов *

/* и записи набора чисел в канал */

/* fd - дескрипторзаписываемогоконцаканала */

/* n - количествогенерируемыхнаборовнеупакованныхчисел */

{

int i;

unsigned short mas [4]; /* массивдлягенерируемогонаборачисел */

int nmas = sizeof mas; /* количествобайт, занимаемыхмассивом */

int nw; /* количествобайт, фактическизаписанных в канал */

/* генерация и запись n наборов */

srand (time (NULL));

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

{

sleep (2); /* ожидание 2 секунды */

mas [0] = (unsigned short) rand () % 32; /* кодсостояния (0 - 31)*/

mas [1] = (unsigned short) rand () % 2; /* признакошибки (0 - 1)*/

mas [2] = (unsigned short) rand () % 2; /* признакзанятости (0 - 1)*/

mas [3] = (unsigned short) rand () % 256; /* количествобайт (0 - 255)*/

if ((nw = write (fd, mas, nmas))!= nmas)

{

myerror (" ошибказаписи "); /* ошибказаписи */

}

printf (" наборотправлен в канал \n");

}

}

void reader (int fd)

/* функциячтениянаборачиселизканала */

{

unsigned short mas [4]; /* массивдлячитаемогонаборачисел */

int nr; /* количествобайт, фактическипрочитанныхизфайла */

int nmas = sizeof mas; /* количествобайт, занимаемыхмассивом */

/* чтениеизфайладанныхпорциямипоblksizeбайт

и выводпрочитанныхчиселнаэкран */

while ((nr = read (fd, mas, nmas)) == nmas)

{

printf (" наборпринятизканала \n");

printf (" Кодсостояния = % hu \n", mas [0]);

printf (" Признакошибки = % hu \n", mas [1]);

printf (" Признакзанятости = % hu \n", mas [2]);

printf (" Количествопереданныхбайт = % hu \n", mas [3]);

}

if (nr < 0)

{

myerror (" ошибкачтения "); /* ошибкачтения */

}

}

void myerror (char * st)

/* функцияобработкиошибоксистемныхвызовов */

{

perror (st);

exit (1);

}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: