Рейтинговые книги
Читем онлайн Основы программирования в Linux - Нейл Мэтью

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 38 39 40 41 42 43 44 45 46 ... 200

#include <sys/mman.h>

void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);

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

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

Параметр prot используется для установки прав доступа к сегменту памяти. Он представляет собой результат поразрядной операции or, примененной к следующим константам:

□ PROT_READ — сегмент может читаться;

□ PROT_WRITE — в сегмент можно писать;

□ PROT_EXEC — сегмент может выполняться;

□ PROT_NONE — к сегменту нет доступа.

Параметр flags контролирует, как изменения, сделанные программой в сегменте, отражаются в других местах; его возможные значения приведены в табл. 3.7.

Таблица 3.7

Константа Описание MAP_PRIVATE Сегмент частный, изменения локальные MAP_SHARED Изменения сегмента переносятся в файл MAP_FIXED Сегмент должен располагаться по заданному адресу addr

Функция msync вызывает запись изменений в части или во всем сегменте памяти обратно а отображенный файл (или считывание из файла).

#include <sys/mman.h>

int msync(void *addr, size_t len, int flags);

Корректируемая часть сегмента задается передачей начального адреса addr и размера len. Параметр flags управляет способом выполнения корректировки с помощью вариантов, приведенных в табл. 3.8.

Таблица 3.8

Константа Описание MS_ASYNC Выполнять запись асинхронно MS_SYNC Выполнять запись синхронно MS_INVALIDATE Обновить другие отражения этого файла так, чтобы они содержали изменения, внесенные этим вызовом

Функция munmap освобождает сегмент памяти.

#include <sys/mman.h>

int munmap(void *addr, size_t len);

В программе mmap.с из упражнения 3.5 показан файл из структур, которые будут корректироваться с помощью функции mmap и обращений в стиле массива. Ядро Linux версий, меньших 2.0, не полностью поддерживает применение функции mmap. Программа работает корректно в системе Sun Solaris и других системах.

Упражнение 3.5. Применение функции mmap

1. Начните с определения структуры RECORD и создайте NRECORDS вариантов, в каждый из которых записывается собственный номер. Они будут добавлены в конец файла records.dat.

#include <unistd.h>

#include <stdio.h>

#include <sys/mman.h>

#include <fcntl.h>

#include <stdlib.h>

typedef struct {

 int integer;

 char string[24];

} RECORD;

#define NRECORDS (100)

int main() {

 RECORD record, *mapped;

 int i, f;

 FILE *fp;

 fp = fopen("records.dat", "w+");

 for (i=0; i<NRECORDS; i++) {

  record.integer = i;

  sprintf(record.string, "RECORD-%d", i);

  fwrite(&record, sizeof(record), 1, fp);

 }

 fclose(fp);

2. Далее измените целое значение записи с 43 на 143 и запишите его в строку 43-й записи.

 fp = fopen("records.dat", "r+");

 fseek(fp, 43*sizeof(record), SEEK_SET);

 fread(&record, sizeof(record), 1, fp);

 record.integer =143;

 sprintf(record.string, "RECORD-%d", record.integer);

 fseek(fp, 43*sizeof(record), SEEK_SET);

 fwrite(&record, sizeof(record), 1, fp);

 fclose(fp);

3. Теперь отобразите записи в память и обратитесь к 43-й записи для того, чтобы изменить целое на 243 (и обновить строку записи), снова используя отображение в память.

 f = open("records.dat", O_RDWR);

 mapped = (RECORD *)mmap(0, NRECORDS*sizeof(record),

  PROT_READ|PROT_WRITE, MAP_SHARED, f, 0);

 mapped[43].integer = 243;

 sprintf(mapped[43].string, "RECORD-%d", mapped[43].integer);

 msync((void *)mapped, NRECORDS*sizeof(record), MS_ASYNC);

 munmap((void *)mapped, NRECORDS*sizeof(record));

 close(f);

 exit(0);

}

В главе 13 вы встретитесь с еще одним средством совместного использования памяти — разделяемой памятью System V.

Резюме

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

Вы также узнали об обработке файлов и каталогов достаточно для того, чтобы превратить "сырое" приложение для работы с компакт-дисками, созданное в конце главы 2, в программу на языке С, применяющую более структурированное решение на базе файлов. Но на этом этапе вы не можете расширить функциональные возможности программы, поэтому мы отложим ее переработку до того времени, когда вы научитесь управлять экраном и клавиатурой, которые будут предметами обсуждения следующих двух глав. 

Глава 4

Окружение Linux

Когда вы пишете программу для ОС Linux (или UNIX и UNIX-подобных систем), следует принимать во внимание то, что программа будет выполняться в многозадачной среде или многозадачном окружении. Это означает, что много программ будет выполняться одновременно и совместно использовать ресурсы компьютера, такие как память, дисковое пространство и циклы центрального процессора. Может даже существовать несколько экземпляров одной и той же программы, выполняющихся одновременно. Важно, чтобы эти программы не мешали друг другу, знали о своем окружении и могли действовать надлежащим образом, избегая конфликтов, таких как попытка писать в один и тот же файл одновременно с другой программой.

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

□ передача аргументов в программы;

□ переменные окружения;

□ определение текущего времени;

□ временные файлы;

□ получение информации о пользователе и рабочем компьютере;

□ формирование и настройка регистрируемых сообщений;

□ выявление ограничений, накладываемых системой.

Аргументы программы

Когда в ОС Linux или UNIX выполняется программа на языке С, она начинается с функции main. В таких программах функция main объявляется следующим образом:

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

Здесь argc — это счетчик аргументов программы, a argv — массив символьных строк, представляющих сами аргументы.

Вы можете встретить программы на языке С для ОС Linux, просто объявляющие функцию main как

main()

Этот вариант тоже работает, поскольку по умолчанию возвращаемому функцией значению будет назначен тип int, а формальные параметры, которые в функции не применяются, не нуждаются в объявлении. Параметры argc и argv остаются на своем месте, но если вы не объявляете их, то и не можете их использовать.

Каждый раз, когда операционная система запускает новую программу, параметры argc и argv устанавливаются и передаются функции main. Обычно эти параметры предоставляются другой программой, часто командной оболочкой, которая запросила у операционной системы запуск новой программы. Оболочка принимает заданную командную строку, разбивает её на отдельные слова и использует их для заполнения массива argv. Помните о том, что до установки параметров argc и argv командная оболочка Linux обычно выполняет раскрытие метасимволов в аргументах, содержащих имена файлов, в то время как оболочка MS-DOS рассчитывает на то, что программы примут аргументы с метасимволами и выполнят собственную постановку.

Например, если мы дадим командной оболочке следующую команду:

1 ... 38 39 40 41 42 43 44 45 46 ... 200
На этой странице вы можете бесплатно читать книгу Основы программирования в Linux - Нейл Мэтью бесплатно.
Похожие на Основы программирования в Linux - Нейл Мэтью книги

Оставить комментарий