My-library.info
Все категории

Марк Митчелл - Программирование для Linux. Профессиональный подход

На электронном книжном портале my-library.info можно читать бесплатно книги онлайн без регистрации, в том числе Марк Митчелл - Программирование для Linux. Профессиональный подход. Жанр: Программирование издательство -, год 2004. В онлайн доступе вы получите полную версию книги с кратким содержанием для ознакомления, сможете читать аннотацию к книге (предисловие), увидеть рецензии тех, кто произведение уже прочитал и их экспертное мнение о прочитанном.
Кроме того, в библиотеке онлайн my-library.info вы найдете много новинок, которые заслуживают вашего внимания.

Название:
Программирование для Linux. Профессиональный подход
Издательство:
-
ISBN:
-
Год:
-
Дата добавления:
17 сентябрь 2019
Количество просмотров:
299
Читать онлайн
Марк Митчелл - Программирование для Linux. Профессиональный подход

Марк Митчелл - Программирование для Linux. Профессиональный подход краткое содержание

Марк Митчелл - Программирование для Linux. Профессиональный подход - описание и краткое содержание, автор Марк Митчелл, читайте бесплатно онлайн на сайте электронной библиотеки My-Library.Info
Данная книга в основном посвящена программированию в среде GNU/Linux. Авторы применяют обучающий подход, последовательно излагая самые важные концепции и методики использования расширенных возможностей системы GNU/Linux в прикладных программах. Читатели научатся писать программы, к интерфейсу которых привыкли пользователи Linux; освоят такие технологии, как многозадачность, многопотоковое программирование, межзадачное взаимодействие и взаимодействие с аппаратными устройствами; смогут улучшить свои программы, сделав их быстрее, надежнее и безопаснее; поймут особенности системы GNU/Linux, ее ограничения, дополнительные возможности и специфические соглашения.Книга предназначена для программистов, уже знакомых с языком С и имеющих базовый опыт работы в GNU/Linux.

Программирование для Linux. Профессиональный подход читать онлайн бесплатно

Программирование для Linux. Профессиональный подход - читать книгу онлайн бесплатно, автор Марк Митчелл

 /* Небольшая пауза. */

 sleep(1);

}


/* Чтение строк из потока, пока он не опустеет. */

void reader(FILE* stream) {

 char buffer[1024];

 /* Чтение данных, пока не будет обнаружен конец потока.

    Функция fgets() завершается, когда встречает символ

    новой строки или признак конца файла. */

 while (!feof(stream)

  && !ferror(stream)

  && fgets(buffer, sizeof (buffer), stream) != NULL)

  fputs(buffer, stdout);

}


int main() {

 int fds[2];

 pid_t pid;


 /* Создание канала. Дескрипторы обоих концов канала

    помещаются в массив FDS. */

 pipe(fds);

 /* порождение дочернего процесса. */

 pid = fork();

 if (pid == (pid_t)0) {

  FILE* stream;

  /* Это дочерний процесс. Закрываем копию входного конца

     канала. */

  close(fds[1]);

  /* Приводим дескриптор выходного конца канала к типу FILE*

     и читаем данные из канала. */

  stream = fdopen(fds[0], "r");

  reader(stream);

  close(fds[0]);

 } else {

  /* Это родительский процесс. */

  FILE* stream;

  /* Закрываем копию выходного конца канала. */

  close(fds[0]);

  /* Приводим дескриптор входного конца канала к типу FILE*

     и записываем данные в канал. */

  stream = fdopen(fds[1], "w");

  writer("Hello, world.", 5, stream);

  close(fds[1]);

 }

 return 0;

}

Сначала в программе объявляется массив fds, состоящий из двух целых чисел. Функция pipe() создает канал и помещает в массив дескрипторы входного и выходного концов канала. Затем функция fork() порождает дочерний процесс. После закрытия выходного конца канала родительский процесс начинает записывать строки в канал. Дочерний процесс читает строки из канала, предварительно закрыв его входной конец.

Обратите внимание на то. что в функции writer() родительский процесс принудительно "выталкивает" буфер канала, вызывая функцию fflush(). Без этого строка могла бы ""застрять" в буфере и отправиться в канал только после завершения родительского процесса.

При вызове команды ls | less функция fork() выполняется дважды: один раз — для дочернего процесса ls, второй раз — для дочернего процесса less. Оба процесса наследуют копии дескрипторов канала, поэтому могут общаться друг с другом. О соединении несвязанных процессов речь пойдет ниже, в разделе 5.4.5, "Каналы FIFO".

5.4.3. Перенаправление стандартных потоков ввода, вывода и ошибок

Часто требуется создать дочерний процесс и сделать один из концов канала его стандартным входным или выходным потоком. В этом случае на помощь приходит функция dup2(), которая делает один файловый дескриптор равным другому. Вот как, например, можно связать стандартный входной поток с файлом fd:

dup2(fd, STDIN_FILENO);

Символическая константа STDIN_FILENO представляет дескриптор файла, соответствующий стандартному потоку ввода (значение этого дескриптора равно 0). Показанная функция закрывает входной поток, а затем открывает его под видом файла fd. Оба дескриптора (0 и fd) будут указывать на одну и ту же позицию в файле и иметь одинаковый набор флагов состояния, т.е. дескрипторы станут взаимозаменяемыми.

Программа, представленная в листинге 5.8, с помощью функции dup2() соединяет выходной. Конец канала со входом команды sort.[16] После создания канала программа "делится" функцией fork() на два процесса. Родительский процесс записывает в канал различные строки, а дочерний процесс соединяет выходной конец канала со своим входным потоком, после чего запускает команду sort.

Листинг 5.8. (dup2.c) Перенаправление выходного потока канала с помощью функции dup2()

#include <stdio.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <unistd.h>


int main() {

 int fds[2];

 pid_t pid;


 /* Создание канала. Дескрипторы обоих концов канала

    помещаются в массив FDS. */

 pipe (fds);

 /* Создание дочернего процесса. */

 pid = fork();

 if (pid == (pid_t)0) {

  /* Это дочерний процесс. Закрываем копию входного конца

    канала */

  close(fds[1]);

  /* Соединяем выходной конец канала со стандартным входным

     потоком. */

  dup2(fds[0], STDIN_FILENO);

  /* Замещаем дочерний процесс программой sort. */

  execlp("sort", "sort", 0);

 } else {

  /* Это родительский процесс. */

  FILE* stream;

  /* Закрываем копию выходного конца канала. */

  close(fds[0]);

  /* Приводим дескриптор входного конца канала к типу FILE*

     и записываем данные в канал. */

  stream = fdopen(fds[1], "w");

  fprintf(stream, "This is a test.n");

  fprintf(stream, "Hello, world.n");

  fprintf(stream, "My dog has fleas.n");

  fprintf(stream, "This program is great.n");

  fprintf(stream, "One fish, two fish.n");

  fflush(stream);

  close(fds[1]);

  /* Дожидаемся завершения дочернего процесса. */

  waitpid(pid, NULL, 0);

 }

 return 0;

}

5.4.4. Функции popen() и pclose()

Каналы часто используются для передачи данных программе, выполняющейся как подпроцесс (или приема данных от нее). Специально для этих целей предназначены функции popen() и pclose(), устраняющие необходимость в вызове функций pipe(), dup2(), exec() и fdopen().

Сравните листинг 5.9 с предыдущим примером (листинг 5.8).

Листинг 5.9. (popen.c) Использование функций popen() и pclose()

#include <stdio.h>

#include <unistd.h>


int main() {

 FILE* stream = popen("sort", "w");

 fprintf(stream, "This is a test.n");

 fprintf(stream, "Hello, world.n");

 fprintf(stream, "My dog has fleasn");

 fprintf(stream, "This program is great.n");

 fprintf(stream, "One fish, two fish.n");

 return pclose(stream);

}

Функция popen() создает дочерний процесс, в котором выполняется команда sort. Один этот вызов заменяет вызовы функций pipe(), fork(), dup2() и execlp(). Второй аргумент, "w", указывает на то, что текущий процесс хочет осуществлять запись в дочерний процесс. Функция popen() возвращает указатель на один из концов канала; второй конец соединяется со стандартным входным потоком дочернего процесса. Функция pclose() закрывает входной поток дочернего процесса, дожидается его завершения и возвращает код статуса.

Первый аргумент функции popen() является командой интерпретатора, выполняемой в подпроцессе /bin/sh. Интерпретатор просматривает переменную среды PATH, чтобы определить, где следует искать команду. Если второй аргумент равен "r", функция возвращает указатель на стандартный выходной поток дочернего процесса, чтобы программа могла читать данные из него. Если второй аргумент равен "w", функция возвращает указатель на стандартный входной поток дочернего процесса, чтобы программа могла записывать данные в него. В случае ошибки возвращается пустой указатель.

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

5.4.5. Каналы FIFO

Файл FIFO (First-In, First-Out — первым пришел, первым обслужен) — это канал, у которого есть имя в файловой системе. Любой процесс может открыть и закрыть такой файл. Процессы, находящиеся на противоположных концах канала, не обязаны быть связанными друг с другом. FIFO-файлы называют именованными каналами.

FIFO-файл создается с помощью команды mkfifo. Путь к файлу указывается в командной строке, например:

% mkfifo /tmp/fifo

% ls -l /tmp/fifo

prw-rw-rw- 1 samuel users 0 Jan 16 14:04 /tmp/fifo

Первый символ в строке режима (p) указывает на то, что файл имеет тип FIFO (именованный канал). Теперь в одном терминальном окне можно осуществлять чтение из файла с помощью команды

% cat < /tmp/fifo

а в другом окне можно выполнять запись в файл:

% cat > /tmp/fifo

Попробуйте во втором окне ввести какой-то текст и нажать <Enter>. Введенный текст немедленно отобразится в первом окне. Канал закрывается нажатием клавиш <Ctrl+D> во втором окне. FIFO-файл удаляется с помощью следующей команды:


Марк Митчелл читать все книги автора по порядку

Марк Митчелл - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки My-Library.Info.


Программирование для Linux. Профессиональный подход отзывы

Отзывы читателей о книге Программирование для Linux. Профессиональный подход, автор: Марк Митчелл. Читайте комментарии и мнения людей о произведении.

Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*
Все материалы на сайте размещаются его пользователями.
Администратор сайта не несёт ответственности за действия пользователей сайта..
Вы можете направить вашу жалобу на почту librarybook.ru@gmail.com или заполнить форму обратной связи.