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

Страницы работы

Содержание работы

Цель работы.

Изучить следующие средства межпроцессного взаимодействия (IPC) в ОС LINUX:           

·  надежные и ненадежные сигналы;

·  именованные и неименованные каналы;

·  очереди сообщений;

·  семафоры и разделяемая память.

1. Ненадежные сигналы.

Следующая программа позволяет изменить диспозицию сигналов, а именно, установить:

·  обработчик пользовательских сигналов SIGUSR1 и SIGUSR2;

·   реакцию по умолчанию на сигнал SIGINT;

·   игнорирование сигнала SIGCHLD;

Порождается процесс-копия и программа уходит в ожидание сигналов.

Листинг 1.1. sig_father_fork.c.

/*

* Ненадежные сигналы

* Файл sig_fatehr.c

*/

#include <stdio.h>

#include <signal.h>

#include <process.h>

#include <sys/wait.h>

#include <sys/siginfo.h>

static void sigusr1_handler( int signo );

static void sigusr2_handler( int signo );

static void sigchld_handler( int signo );

int main( void )

{

pid_t pid = getpid( );

printf( "Fatehr process is started! " );     

printf( "PID: %d\n", pid );

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

signal( SIGINT, SIG_DFL );                     // SIGINT реакция по умолчанию                            

signal( SIGUSR1, sigusr1_handler ); 

signal( SIGUSR2, sigusr2_handler );   

signal( SIGCHLD,  SIG_DFL );                  // игнорирование SIGCHLD 

//signal( SIGCHLD,  sigchld_handler );        // обработчик SIGCHLD

pid_t chld_pid = fork( );

if( chld_pid == -1 )

{

printf( "Create proc error!\n" );

return( 1 );

}

else if( chld_pid == 0 )

{

pid_t child_pid = getpid( );

printf( "Child process is started! " );

printf( "PID: %d\n", child_pid );

// Посылаем SIGUSR1 процессу-родителю //                               

kill( pid, SIGUSR1 );

while( 1 )   sleep( 2 );                     

}

else {      

while( 1 )   sleep( 2 );              

}     

return( 0 );

}

static void sigusr1_handler( int signo )

{

signal( SIGUSR1, sigusr1_handler );          

printf("Signal SIGUSR1 is handled!\n");

}

static void sigusr2_handler( int signo )

{     

signal( SIGUSR2, sigusr2_handler );

printf("Signal SIGUSR2 is handled!\n");

}

static void sigchld_handler( int signo )

{

signal( SIGCHLD, sigchld_handler );

printf("Signal SIGCHLD is handled!\n");

}

Результаты работы программы.

# ./sig_father_fork&

[1] 1982512

# Fatehr process is started! PID: 1982512

Child process is started! PID: 1986609

Signal SIGUSR1 is handled!

# kill -SIGUSR1 1982512

Signal SIGUSR1 is handled!

# kill -SIGUSR1 1986609

Signal SIGUSR1 is handled!

# kill -SIGUSR2 1982512

Signal SIGUSR2 is handled!

# kill -SIGUSR1 1986609

Signal SIGUSR1 is handled!

Таким образом, при создании нового процесса с помощью fork( ) обработчики сигналов наследуются.

Сигнал SIGCHLD посылается процессом-потомком при его завершении процессу-родителю. Чтобы это проверить, установим обработчик сигнала SIGCHLD для процесса-родителя и завершим процесс-потомок из консоли.

# ./sig_father_fork&

[1] 5918763

# Fatehr process is started! PID: 5918763

Child process is started! PID: 5922860

Signal SIGUSR1 is handled!

# kill -SIGINT 5922860

# Signal SIGCHLD is handled!   

Таким образом, сигнал SIGCHLD можно использовать для синхронизации работы процесса-родителя со своими потомками.

2. Надежные сигналы.

В следующей программе реализована функция mysignal(), интерфейс и использование которой похожи на функцию signal(), которая использует ненадежные сигналы.

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

Листинг 2.1. sigact.c.

#include <stdio.h>

#include <stdlib.h>

#include <signal.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

typedef void (*fp)(int);

fp mysignal( int, fp );

void sigint_handler( int );

void sigusr1_handler( int );

void sigusr2_handler( int );

int main( void )

{

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

mysignal( SIGINT, sigint_handler );                  // Игнорирование SIGINT

mysignal( SIGUSR1, sigusr1_handler );                // Установка обработчика

mysignal( SIGUSR2, sigusr2_handler );                // для SIGUSR1 и SIGUSR2

while( 1 )

{

sleep( 3 );

}

return EXIT_SUCCESS;

}

/* Надежная обработка сигналов */

fp mysignal( int signo, fp handler )

{

struct sigaction    act,

old_act;

/* Установка маски сигналов */

act.sa_handler = handler;

sigemptyset( &act.sa_mask );

act.sa_flags = 0;

Похожие материалы

Информация о работе