Нейл Мэтью - Основы программирования в Linux
- Название:Основы программирования в Linux
- Автор:
- Жанр:
- Издательство:«БХВ-Петербург»
- Год:2009
- Город:Санкт-Петербург
- ISBN:978-5-9775-0289-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Нейл Мэтью - Основы программирования в Linux краткое содержание
В четвертом издании популярного руководства даны основы программирования в операционной системе Linux. Рассмотрены: использование библиотек C/C++ и стандартных средств разработки, организация системных вызовов, файловый ввод/вывод, взаимодействие процессов, программирование средствами командной оболочки, создание графических пользовательских интерфейсов с помощью инструментальных средств GTK+ или Qt, применение сокетов и др. Описана компиляция программ, их компоновка c библиотеками и работа с терминальным вводом/выводом. Даны приемы написания приложений в средах GNOME® и KDE®, хранения данных с использованием СУБД MySQL® и отладки программ. Книга хорошо структурирована, что делает обучение легким и быстрым.
Для начинающих Linux-программистов
Основы программирования в Linux - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
int send_resp_to_client(const message_db_t mess_to_send) {
struct msg_passed my_msg;
#if DEBUG_TRACE
printf("%d :- send_resp_to_client()\n", getpid());
#endif
my_msg.real_message = mess_to_send;
my_msg.msg_key = mess_to_send.client_pid;
if (msgsnd(cli_qid, (void *)&my_msg, sizeof(mess_to_send), 0) == -1) {
return(0);
}
return(1);
}
Пересмотр функций клиента
Теперь нужно внести изменения в клиентские функции.
1. Когда клиент стартует, ему нужно найти идентификаторы серверной и клиентской очередей. Клиент не создает очереди. Если сервер не работает, эта функция завершится аварийно, поскольку не существует очередей сообщений.
int client starting() {
#if DEBUG_TRACE
printf("%d :- client_starting\n", getpid());
#endif
serv_qid = msgget((key_t)SERVER_MQUEUE, 0666);
if (serv_qid == -1) return(0);
cli_qid = msgget((key_t)CLIENT_MQUEUE, 0666);
if (cli_qid == -1) return(0);
return(1);
}
2. Как и в случае сервера, когда клиент завершает работу, вы задаете некорректные значения глобальных переменных. Это позволит выявить ошибки при попытке клиента отправлять сообщения после вызова функции client_ending
.
void client_ending() {
#if DEBUG_TRACE
printf("%d :- client_ending()\n", getpid());
#endif
serv_qid = -1;
cli_qid = -1;
}
3. Для отправки сообщения серверу сохраните данные в своей структуре. Учтите, что вы должны задать ключ сообщения. Поскольку 0 — недопустимое значение для ключа, незаданный ключ означает, что он принимает (очевидно) случайное значение, поэтому иногда эта функция может возвращать ошибку, если значение оказывается нулевым.
int send_mess_to_server(message_db_t mess_to_send) {
struct msg_passed my_msg;
#if DEBUG_TRACE
printf("%d send_mess_to_server()\n", getpid());
#endif
my_msg.real_message = mess_to_send;
my_msg.msg_key = mess_to_send.client_pid;
if (msgsnd(serv_qid, (void *)&my_msg, sizeof(mess_to_send) , 0) == -1) {
perror("Message send failed");
return(0);
}
return(1);
}
4. При получении сообщения от сервера клиент использует ID процесса для получения только сообщений, адресованных ему, пропуская сообщения, предназначенные другим клиентам.
int read_resp_from_server(message_db_t *rec_ptr) {
struct msg_passed mymsg;
#if DEBUG_TRACE
printf("%d :- read_resp_from_server()\n", getpid());
#endif
if (msgrcv(cli_qid, (void *)&my_msg, sizeof(*rec_ptr), getpid(), 0) == -1) {
return(0);
}
*rec_ptr = my_msg.real_message;
return(1);
}
5. Для сохранения совместимости с файлом pipe_imp.c необходимо объявить четыре дополнительные функции. Но в вашей программе они будут пустыми. Операции, которые они реализовывали в случае применения каналов, больше не нужны.
int start_resp_to_client(const message_db_t mess_to_send) {
return(1);
}
void end_resp_to_client(void) {}
int start_resp_from_server(void) {
return(1);
}
void end_resp_from_server(void) {}
Теперь вы можете просто запустить сервер, выполняющий в фоновом режиме реальное сохранение и извлечение данных, и затем выполнить клиентское приложение для подключения к серверу с помощью сообщений.
Все, что вы должны сделать, — это заменить интерфейсные функции из главы 11 другой реализацией, применяющей очереди сообщений. Преобразование приложения для использования очередей сообщений показывает мощь этого средства IPC, т.к. вам требуется меньше функций, чем в случае применения каналов, и даже эти необходимые функции гораздо проще, чем в предыдущей версии приложения.
Команды состояния IPC
Несмотря на то, что для соответствия требованиям X/Open этого не требуется, большинство систем Linux предоставляет набор команд, обеспечивающих доступ к данным IPC в режиме командной строки и удаление потерянных средств IPC. Существуют команды ipcs
и ipcrm
, очень полезные при разработке программ.
Один из досадных недостатков средств IPC состоит в том, что плохо написанная программа или программа, по какой-либо причине завершившаяся аварийно, может оставить свои ресурсы IPC (например, данные в очереди сообщений) еще долго блуждающими в системе без определенной цели после завершения программы. Такое поведение может привести к аварийному завершению нового запуска программы, поскольку она рассчитывает начать выполнение в очищенной системе, а на самом деле находит эти блуждающие ресурсы. Команды состояния ( ipcs
) и удаления ( ipcrm
) позволяют проверить систему и очистить ее от ненужных средств IPC.
Отображение состояния семафора
Для проверки состояния семафоров в системе примените команду ipcs -s
. Если какие-то семафоры присутствуют, вывод команды будет выглядеть следующим образом:
$ ipcs -s
------ Semaphore Arrays ------
key semid owner perms nsems
0x4d00df1a 768 rick 666 1
Для удаления семафоров, случайно оставленных программами, вы можете использовать команду ipcrm
. Для удаления только что отображенного семафора примените (в Linux) следующую команду:
$ ipcrm -s 768
В некоторых более старых системах Linux используется несколько иной синтаксис команды:
$ ipcrm sem 768
Но этот устаревший стиль редко встречается в наше время. Формат, подходящий для вашей конкретной системы, ищите на страницах интерактивного справочного руководства.
Отображение состояния совместно используемой памяти
Многие системы предоставляют программы режима командной строки для доступа не только к сведениям о семафорах, но и к подробным данным совместно используемой памяти. К ним относятся команды ipcs -m
и ipcrm -m < id >
(или ipcrm shm < id >
).
Далее приведен пример вывода команды ipcs -m
:
$ ipcs -m
------ Shared Memory Segments ------
key shmid owner perms bytes nattch status
0x00000000 384 rick 666 4096 2 dest
Здесь показан единственный сегмент совместно используемой памяти объемом 4 Кбайт, присоединенный к двум процессам.
Команда ipcrm -m < id >
позволяет удалить совместно используемую память. Она бывает полезной, когда программа завершается аварийно при попытке убрать такую память.
Отображение состояния очереди сообщений
Для очередей сообщений предназначены команды ipcs -q
и ipcrm -q < id
> (или ipcrm msg < id >
).
Далее приведен пример вывода команды ipcs -q
:
$ ipcs -q
------ Message Queues ------
key msqid owner perms used-bytes messages
0x000004d2 3384 rick 666 2048 2
В нем показаны в очереди сообщений два сообщения общим объемом 2048 байтов. Команда ipcrm -q < id >
позволяет удалить очередь сообщений.
Резюме
В этой главе вы познакомились с тремя разновидностями средств взаимосвязи процессов, которые стали широко применяться в ОС UNIX System V.2 и были доступны в системе Linux, начиная с ранних версий ее дистрибутивов. Вы рассмотрели предлагаемые ими сложные функциональные возможности и, после того как поняли принципы их функционирования, оценили обеспечиваемое ими эффективное решение для удовлетворения многих потребностей межпроцессного взаимодействия.
Читать дальшеИнтервал:
Закладка: