Самодел 2 (1114717), страница 12

Файл №1114717 Самодел 2 (Старые версии Машбука или нечто подобное) 12 страницаСамодел 2 (1114717) страница 122019-05-08СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 12)

В стандартной ситуации (при отсутствии переполнения) система гарантирует атомарность операции записи, т. е. при одновременной записи нескольких процессов в канал их данные не перемешиваются.

Пример использования канала:

П ример 1.

Один процесс может использовать канал только для себя – как здесь показано, будет фактически осуществлятся пересылка данных самому себе – из одной переменной в другую.

(При работе с каналом, как уже было сказано выше, можно использовать фукции для работы с обычным файлом).

int main(int argc, char **argv)

{

char s*=”chanel”;

char buf[80];

int pipes[2];

pipe(pipes);

write(pipes[1],s,strlen(s)+1);

read(pipes[0],buf,strlen(s)+1);

close(pipes[0]);

close(pipes[1]);

printf(“%s\n”,buf);

}

Пример 2.

Чаще всего, однако, канал используется для обмена данными между несколькими процессами. При организации такого обмена используется тот факт, что при порождении сыновнего процесса посредством системного вызова fork() наследуется таблица файловых дескрипторов процесса-отца, т.е. все файловые дескрипторы, доступные процессу-отцу, будут доступны и процессу-сыну. Таким образом, если перед порождением потомка был создан канал, файловые дескрипторы для доступа к каналу будут унаследованы и сыном. В итоге обоим процессам оказываются доступны дескрипторы, связанные с каналом, и они могут использовать канал для обмена данными.

Схема взаимодействия процессов с использованием канала.



(сам пример 2.)

int main(int argc, char **argv)

{

int fd[2];

pipe(fd);

if(fork())

{/*процесс-родитель*/

close(fd[0]); /* закрываем ненужный дескриптор */

write (fd[1], …);

close(fd[1]);

} else {/*процесс-потомок*/

close(fd[1]); /* закрываем ненужный дескриптор */

while(read (fd[0], …))

{

}

}

}

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

Как правило, канал используется как однонаправленное средство передачи данных, т.е. только один из двух взаимодействующих процессов осуществляет запись в него, а другой процесс осуществляет чтение[это правило не является обязательным, но для корректной организации двустороннего обмена через один канал требуется дополнительная синхронизация], при этом каждый из процессов закрывает не используемый им дескриптор. Это особенно важно для неиспользуемого дескриптора записи в канал, т.к. именно при закрытии пишущей стороны канала в него помещается символ конца файла. Если, к примеру, в рассмотренном примере 14 процесс-потомок не закроет свой дескриптор записи в канал, то при последующем чтении из канала, исчерпав все данные из него, он будет заблокирован, т.к. записывающая сторона канала будет открыта, и следовательно, читающий процесс будет ожидать очередной порции данных.

Пример. Реализация конвейера.

print|wc – вывод программы print будет подаваться на вход программы wc. Программа print печатает некоторый текст. Программа wc считает количество прочитанных строк, слов и символов.

#include <stdio.h>

int main(int argc, char **argv)

{

int fd[2];

pipe(fd); /*организован канал*/

if(fork())

{

/*процесс-родитель*/

dup2(fd[1],1);

/*отождествили стандартный вывод с файловым дескриптором канала, предназначенным для записи*/

close(fd[1]); /*закрыли файловый дескриптор канала, предназначенный для записи */

close(fd[0]); /*закрыли файловый дескриптор канала, предназначенный для чтения */

exelp(“print”,”print”,0); /*запустили программу print */

}

/*процесс-потомок*/

dup2(fd[0],0);

/*отождествили стандартный ввод с файловым дескриптором канала, предназначенным для чтения*/

close(fd[0]);

/* закрыли файловый дескриптор канала, предназначенный для чтения */

close(fd[1]);

/* закрыли файловый дескриптор канала, предназначенный для записи */

execl(“/usr/bin/wc”,”wc”,0); /* запустили программу wc */

}

Пример 3. Совместное использование сигналов и каналов – «пинг-понг».

Пример программы с использованием каналов и сигналов для осуществления связи между процессами – весьма типичной ситуации в системе. При этом на канал возлагается роль среды двусторонней передачи информации, а на сигналы – роль системы синхронизации при передаче информации.

Здесь один из процессов каким-то образом получает некоторое вполне определённое целое число. Он увеличивает это число на 1 и посылает другому. Второй процесс, получив новое число, делает с ним то же самое – увеличивает на 1 и посулает первому прочессу.И так далее, пока число не достигнет некоего максимума – тогда оба процесса завершаются.

В данном примере пинг-понг организован между отцом и сыном.

#include <signal.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#define MAX_CNT 100

int target_pid, cnt;

int fd[2];

int status;

void SigHndlr (int s)

{

/* в обработчике сигнала происходит и чтение, и запись */

signal(SIGUSR1, SigHndlr);

if (cnt < MAX_CNT)

{

read(fd[0], &cnt, sizeof(int));

printf("%d \n", cnt);

cnt++;

write(fd[1], &cnt, sizeof(int));

/* посылаем сигнал второму: пора читать из канала */

kill(target_pid, SIGUSR1);

}

else

if (target_pid == getppid())

{

/* условие окончания игры проверяется потомком */

printf("Child is going to be terminated\n");

close(fd[1]); close(fd[0]);

/* завершается потомок */

exit(0);

} else kill(target_pid, SIGUSR1);

}

int main(int argc, char **argv)

{

pipe(fd); /* организован канал */

signal(SIGUSR1, SigHndlr);

/* установлен обработчик сигнала для обоих процессов */

cnt = 0;

if (target_pid = fork())

{

/* Предку остается только ждать завершения потомка */

wait(&status);

printf("Parent is going to be terminated\n");

close(fd[1]); close(fd[0]);

return 0;

}

else

{

/* процесс-потомок узнает PID родителя */

target_pid = getppid();

/* потомок начинает пинг-понг */

write(fd[1], &cnt, sizeof(int));

kill(target_pid, SIGUSR1);

for(;;); /* бесконечный цикл */

}

}

Именованные каналы.

Именованные каналы отличаются от неименованных тем, что к ним можно обращаться по имени, как к файлам.

Именованный канал – это фактически файл, использующий организацию FIFO.

Для создания именованного канала чаще всего используется функция:

int mkfifo (char *pathname, mode_t mode)

pathname – имя создаваемого канала

mode – права доступа владельца/ группы/прочих

После создания именованного канала любой процесс может установит с ним связь посредством системного вызова open(). При этом действуют следующие правила:

- если процесс открывает FIFO-файл для чтения, он блокируется до тех пор, пока какой-либо процесс не откроет тот же канал на запись

- если процесс открывает FIFO-файл на запись, он будет заблокирован до тех пор, пока какой-либо процесс не откроет тот же канал на чтение

- процесс может избежать такого блокирования, указав в вызове open() специальный флаг (в разных версиях ОС он может иметь разное символьное обозначение – O_NONBLOCK или O_NDELAY). В этом случае в ситуациях, описанных выше, вызов open() сразу же вернет управление процессу

Правила работы с именованными каналами, в частности, особенности операций чтения-записи, полностью аналогичны неименованным каналам. То есть также можно пользоваться теми же функциями.

Пример:

Здесь один из процессов является сервером, предоставляющим некоторую услугу, другой же процесс, который хочет воспользоваться этой услугой, является клиентом. Клиент посылает серверу запросы на предоставление услуги, а сервер отвечает на эти запросы.

/* процесс-сервер*/

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/file.h>

int main(int argc, char **argv)

{

int fd;

int pid;

mkfifo("fifo", S_IFIFO | 0666);

/*создали специальный файл FIFO с открытыми для всех правами доступа на чтение и запись*/

fd = open ("fifo", O_RDONLY | O_NONBLOCK);

/* открыли канал на чтение*/

while ( read (fd, &pid, sizeof(int) ) == -1) ;

printf ("Server %d got message from %d !\n", getpid(), pid);

close (fd);

unlink ("fifo");/*уничтожили именованный канал*/

}

/* процесс-клиент*/

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/file.h>

int main(int argc, char **argv)

{

int fd;

int pid=getpid( );

fd = open ("fifo", O_RDWR);

write (fd, &pid, sizeof(int));

close (fd);

}

Межпроцессное взаимодействие, проводимое по модели «главный-подчинённый».

Трассировка – возможна между родственными процессами: процесс-родитель может вести трассировку только непосредственно порожденных им потомков, при этом процесс-потомок должен дать разрешение на это.

Системный вызов ptrace()

Основой системный вызов, используемый при трассировке.

#include <sys/ptrace.h>

int ptrace(int cmd, int pid, int addr, int data);

cmd – код выполняемой команды

pid – идентификатор процесса-потомка

addr – некоторый адрес в адресном пространстве процесса-потомка

data – слово информации.

Здесь вместо параметра cmd следует указать код команды, которую необходимо исполнить. Ниже представлены возможные варианты этих кодов:

cmd = PTRACE_TRACEME — ptrace() с таким кодом операции сыновний процесс вызывает в самом начале своей работы, позволяя тем самым трассировать себя. Все остальные обращения к вызову ptrace() осуществляет процесс-отладчик.

cmd = PTRACE_PEEKDATA - чтение слова из адресного пространства отлаживаемого процесса по адресу addr , ptrace() возвращает значение этого слова.

cmd = PTRACE_PEEKUSER — чтение слова из контекста процесса. Речь идет о доступе к пользовательской составляющей контекста данного процесса, сгруппированной в некоторую структуру, описанную в заголовочном файле <sys/user.h>. В этом случае параметр addr указывает смещение относительно начала этой структуры. В этой структуре размещена такая информация, как регистры, текущее состояние процесса, счетчик адреса и так далее. ptrace() возвращает значение считанного слова.

cmd = PTRACE_POKEDATA — запись данных, размещенных в параметре data, по адресу addr в адресном пространстве процесса-потомка.

cmd = PTRACE_POKEUSER — запись слова из data в контекст трассируемого процесса со смещением addr. Таким образом можно, например, изменить счетчик адреса трассируемого процесса, и при последующем возобновлении трассируемого процесса его выполнение начнется с инструкции, находящейся по заданному адресу.

cmd = PTRACE_GETREGS, PTRACE_GETFREGS — чтение регистров общего назначения (в т.ч. с плавающей точкой) трассируемого процесса и запись их значения по адресу data.

Характеристики

Тип файла
Документ
Размер
4,18 Mb
Тип материала
Высшее учебное заведение

Список файлов лекций

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6537
Авторов
на СтудИзбе
301
Средний доход
с одного платного файла
Обучение Подробнее