Цель работы.
Изучить следующие средства межпроцессного взаимодействия (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;
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.