Средства межпроцессного взаимодействия (IPC) в ОС LINUX. Семафоры и разделяемая память. Ненадежные сигналы, страница 7

#include <semaphore.h>

#include <sys/mman.h>

#include <fcntl.h>

#include <errno.h>

#include <signal.h>

#include "../6_sem_server_ver_2/shared_mem.h"

void sigint_handler( int );

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

{

struct SharedMem *p_shmem;

int    fd_shm;

char   msg[ MAX_MSG_SIZE ];

/* Открытие и отображение объекта разделяемой памяти */

fd_shm = shm_open( SHM_NAME, O_RDWR, PERM );

if( fd_shm < 0 )

{

printf( "Client: open shared memory error!!!\n");

exit(3);

}

p_shmem = mmap( NULL, sizeof(struct SharedMem), PROT_READ | PROT_WRITE, MAP_SHARED, fd_shm, 0);

close( fd_shm );

printf( "Client: start.\n" );

signal( SIGINT, sigint_handler );

int          i;

long   offset;

char   pid_str[32];

sprintf( pid_str, "PID=%d: ", getpid());

strcpy( msg, pid_str );

/* Цикл отправки сообщений серверу */

for ( i=0; ;++i )

{

write( 1, "Message: ", 9 );

scanf( "%s", &msg[ strlen(pid_str) ] );

sem_wait( &(p_shmem->nempty) );

sem_wait( &(p_shmem->mutex) );

offset = p_shmem->msg_offset[ p_shmem->nput ];

if( ++(p_shmem->nput) >= MAX_NUM_MSG )

{

p_shmem->nput = 0;

}

sem_post( &(p_shmem->mutex) );

strcpy( &(p_shmem->msg_data[offset] ), msg );

sem_post( &(p_shmem->nstored) );

}

return EXIT_SUCCESS;

}

void sigint_handler( int signo )

{

printf( "\nClient: terminate.\n");

exit(0);

}

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

Завершение программы так же осуществляется по сигналу SIGINT.

Результаты работы приложения.

Консоль сервера

Консоль клиента 1

Server: start.

Message: PID=1396778: hi!

Message: PID=1396777: yo!

Message: PID=1396776: hello!

Message: PID=1396778: 666

Message: PID=1396777: qwerty

Message: PID=1396776: ololololol

Server: terminate. Shared memory deleted.

Client: start. PID=1396778:

Message: hi!

Message: 666

Message:

Client: terminate.

Консоль клиента 2

Client: start. PID=1396777:

Message: yo!

Message: qwerty

Message:

Client: terminate.

Консоль клиента 3

Client: start. PID=1396776:

Message: hello!

Message: ololololol

Message:

Client: terminate.

7. Межсетевой обмен сообщениями с применением IPCPosix.

На примере очереди сообщений.

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

Сервер создает очередь сообщений, а клиенту указывается путь к файлу очереди через /net/<имя узла>/.

Пример работы программы из пункта 1.5.

            Листинг 7.1. Программа-сервер. Файл msg_server.c.

/*

* Сообщения Posix

* Программа сервера

*/

#include <stdlib.h>

#include <stdio.h>

#include <unistd.h>

#include <signal.h>

#include <mqueue.h>

#include "mysignal.h"

#define                   PERM   0666

#define             QUEUE_NAME  "server_queue"

mqd_t               msg_queue_id;

struct mq_attr      msg_queue_attr;

struct sigevent notification;

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

{

printf( "Server: start.\n" );

/* Создаем очередь сообщений или открываем существующую */

msg_queue_attr.mq_maxmsg = 1024;

msg_queue_attr.mq_msgsize = BUF_LEN;

msg_queue_id = mq_open( QUEUE_NAME, O_RDWR | O_CREAT, PERM, &msg_queue_attr );

if( msg_queue_id < 0 )

{

printf( "Server: create/open queue error!!!\n" );

exit(1);

}

/* Устновка диспозиции для SIGINT */

signal( SIGINT, sigint_handler );

/* Устанавливаем режим уведомления о сообщении сигналом SIGUSR1 */

signal( SIGUSR1, sigusr1_handler );