Слово состояния устройства в системе ввода-вывода представляется в виде:
№ разряда | ||||||||||||||||
Значение | 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);
}