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. Профессиональный подход - читать книгу онлайн бесплатно, автор Марк Митчелл

  mmap(NULL, alloc_size, PROT_WRITE, MAP_PRIVATE, fd, 0);

 close(fd);

 /* Запись на страницу для получения ее копии в частное

    использование. */

 memory[0] = 0;

 /* Запрет на запись в память. */

 mprotect(memory, alloc_size, PROT_NONE);


 /* Попытка записи в память. */

 memory[0] = 1;


 /* Удаление памяти. */

 printf("all donen");

 munmap(memory, alloc_size);

 return 0;

}

Программа работает по следующей схеме.

1. Задается обработчик сигнала SIGSEGV.

2. Файл /dev/zero отображается в памяти, из которой выделяется одна страница. В эту страницу записывается инициализирующее значение, благодаря чему программе предоставляется частная копия страницы.

3. Программа защищает память, вызывая функцию mprotect() с флагом PROT_NONE.

4. Когда программа впоследствии обращается к памяти, Linux посылает ей сигнал SIGSEGV, который обрабатывается в функции segv_handler(). Обработчик сигнала отменяет защиту памяти, разрешая выполнить операцию записи.

5. Программа удаляет область память с помощью функции munmap().

8.10. Функция nanosleep(): высокоточная пауза

Функция nanosleep() является более точной версией стандартной функции sleep(), принимая указатель на структуру типа timespec, где время задается с точностью до наносекунды, а не секунды. Правда, особенности работы ОС Linux таковы, что реальная точность оказывается равной 10 мс, но это все равно выше, чем в функции sleep(). Функцию nanosleep() можно использовать в приложениях, где требуется запускать различные операции с короткими интервалами между ними.

В структуре timespec имеются два поля:

■ tv_sес — целое число секунд;

■ tv_nsec — дополнительное число миллисекунд (должно быть меньше, чем 109).

Работа функции nanosleep(), как и функции sleep(), прерывается при получении сигнала. При этом функция возвращает значение -1, а в переменную errno записывается код EINTR. Но у функции nanosleep() есть важное преимущество. Она принимает дополнительный аргумент — еще один указатель на структуру timespec, в которую (если указатель не равен NULL) заносится величина оставшегося интервала времени (т.е. разница между запрашиваемым и прошедшим промежутками времени). Благодаря этому можно легко возобновлять прерванные операции ожидания.

В листинге 8.8 показана альтернативная реализация функции sleep(). В отличие от стандартного системного вызова эта функция может принимать дробное число секунд и возобновлять операцию ожидания в случае прерывания по сигналу.

Листинг 8.8. (better_sleep.c) Высокоточная реализация функции sleep()

#include <errno.h>

#include <time.h>


int better_sleep(double sleep_time) {

 struct timespec tv;

 /* Заполнение структуры timespec на основании указанного числа

    секунд. */

 tv.tv_sec = (time_t)sleep_time;

 /* добавление неучтенных выше наносекунд. */

 tv.tv_nsec = (long)((sleep_time - tv.tv_sec) * 1e+9);


 while (1) {

  /* Пауза, длительность которой указана в переменной tv.

     В случае прерывания по сигналу величина оставшегося

     промежутка времени заносится обратно в переменную tv. */

  int rval = nanosleep(&tv, &tv);

  if (rval == 0)

   /* пауза успешно окончена. */

   return 0;

  else if (errno == EINTR)

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

   continue;

  else

   /* Какая-то другая ошибка. */

   return rval;

 }

 return 0;

}

8.11. Функция readlink(): чтение символических ссылок

Функция readlink() определяет адресата символической ссылки. Она принимает три аргумента: путь к символической ссылке, буфер для записи адресата и длина буфера. Как ни странно, путевое имя, помещаемое в буфер, не завершается нулевым символом. Но поскольку в третьем аргументе возвращается длина буфера, добавить этот символ несложно.

Если первый аргумент не является символической ссылкой, функция readlink() возвращает -1, а в переменную errno записывается константа EINVAL.

Программа, представленная в листинге 8.9, показывает адресата символической ссылки, заданной в командной строке.

Листинг 8.9. (print-symlink.с) Отображение адресата символической ссылки

#include «errno.h>

#include <stdio.h>

#include <unistd.h>


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

 char target_path[256];

 char* link_path = argv[1];


 /* Попытка чтения адресата символической ссылки. */

 int len =

  readlink(link_path, target_path, sizeof(target_path));


 if (len == -1) {

  /* Функция завершилась ошибкой. */

  if (errno == EINVAL)

   /* Это не символическая ссылка. */

   fprintf(stderr, "%s is not a symbolic linkn", link_path);

  else

   /* Произошла какая-то другая ошибка. */

   perror("readlink");

  return 1;

 } else {

  /* Завершаем путевое имя нулевым символом. */

  target_path[len] = '';

  /* Выводим результат. */

  printf("%sn", target_path);

  return 0;

 }

}

Ниже показано, как создать символическую ссылку и проверить ее с помощью программы print-symlink:

% ln -s /usr/bin/wc my_link

% ./print-symlink my_link

/usr/bin/wc

8.12. Функция sendfile(): быстрая передача данных

Функция sendfile() — это эффективный механизм копирования данных из одного файлового дескриптора в другой. Дескрипторам могут соответствовать дисковые файлы, сокеты или устройства.

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

Функция sendfile() устраняет потребность в создании промежуточного буфера. Ей передаются дескриптор для записи, дескриптор для чтения, указатель на переменную смещения и число копируемых данных. Переменная смещения определяет позицию входного файла, с которой начинается копирование (0 — это начало файла). После окончания копирования переменная будет содержать смещение конца блока. Функция sendfile() объявлена в файле <sys/sendfile.h>.

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

Листинг 8.10. (сору.с) Копирование файла с помощью функции sendfile()

#include <fcntl.h>

#include <stdlib.h>

#include <stdio.h>

#include <sys/sendfile.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <unistd.h>


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

 int read_fd;

 int write_fd;

 struct stat stat_buf;

 off_t offset = 0;


 /* Открытие входного файла. */

 read_fd = open(argv[1], O_RDONLY);

 /* Определение размера входного файла. */

 fstat(read_fd, &stat_buf);

 /* Открытие выходного файла для записи. */

 write_fd =

  open(argv[2], O_WRONLY | O_CREAT, stat_buf.st_mode);

 /* Передача данных из одного файла в другой. */

 sendfile(write_fd, read_fd, &offset, stat_buf.st_size);

 /* Закрытие файлов. */

 close(read_fd);

 close(write_fd);


 return 0;

}

Функция sendfile() часто используется для повышения эффективности копирования. Она широко применяется Web-серверами и сетевыми демонами, предоставляющими файлы по сети клиентским программам. Запрос обычно поступает через сокет. Серверная программа открывает локальный дисковый файл, извлекает из него данные и записывает их в сокет. Благодаря функции sendfile() эта операция существенно ускоряется.

8.13. Функция setitimer(): задание интервальных таймеров

Функция setitimer() является обобщением системного вызова alarm(). Она планирует доставку сигнала по истечении заданного промежутка времени.


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

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


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

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

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