/* Блокировка сигнала SIGINT*/
if( signo != SIGINT )
{
sigaddset( &act.sa_mask, SIGINT );
}
/* Установка диспозиции */
if( sigaction( signo, &act, &old_act ) < 0)
{
return ( SIG_ERR );
}
return (old_act.sa_handler);
}
/* Обработчик сигнала SIGINT */
void sigint_handler( int signo )
{
printf( "SIGINT is handled!!!\n" );
}
/* Обработчик сигнала SIGUSR1 */
void sigusr1_handler( int signo )
{
raise( SIGINT );
printf( "Wait...\n" );
sleep( 20 );
printf( "SIGUSR1 is handled!!!\n" );
}
/* Обработчик сигнала SIGUSR2 */
void sigusr2_handler( int signo )
{
printf( "SIGUSR2 is handled!!!\n" );
}
Результаты работы программы.
# kill -s SIGINT 6725678
SIGINT is handled!!!
# kill -s SIGUSR2 6725678
SIGUSR2 is handled!!!
# kill -s SIGUSR1 6725678
Wait...
SIGUSR1 is handled!!!
SIGINT is handled!!!
Из обработчика сигнала SIGUSR1 процессом посылается сигнал SIGINT самому себе с помощью функции raise(), но SIGINT ожидает завершения обработки SIGUSR1, потому что так установлена маска.
Для сигнала SIGUSR2 маска не установлена, поэтому он может прервать обработку сигнала SIGUSR1:
# kill -s SIGUSR1 6725678
# kill -s SIGUSR2 6725678
SIGUSR2 is handled!!!
SIGUSR1 is handled!!!
SIGINT is handled!!!
Преимущества надежных сигналов по сравнению с ненадежным:
· Диспозиция устанавливается только один раз, и диспозицию не нужно устанавливать каждый раз в функции-обработчике.
· При установке диспозиции, можно указать какие сигналы будут блокироваться на время обработки конкретного сигнала, это значительно увеличивает надежность обработки сигнала.
3. Неименованные каналы.
В следующей программе реализовано взаимодействие двух родственных процессов с помощью неименованного канала.
Процесс-потомок открывает на чтение произвольный текстовый файл и записывает считываемую из него информацию в созданный неименованный канал. Процесс-родитель считывает из канала информацию и записывает в новый текстовый файл.
Имена входного и выходного файлов задаются из командной строки.
Листинг 3. pipe.c.
/*
* Неименованные каналы
*/
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
int main( int argc, char *argv[] )
{
/* Проверка аргументов коммандной сроки */
if( argc < 3 )
{
printf( "Father: Error - command line arg!!!\n" );
exit(1);
}
int file_ds[2];
int src_file;
int dst_file;
char buf[1];
/* Создаем pipe */
if( pipe(file_ds) < 0 )
{
printf( "Father: Create pipe error!!!\n" );
exit(1);
}
printf( "Father: pipe created.\n" );
/* Создаем новый процесс */
pid_t chld_pid;
chld_pid = fork();
switch( chld_pid )
{
case -1:
{
printf( "Father: Create pocess error!!!\n" );
exit(2);
break;
}
case 0:
{
src_file = open( argv[1], O_RDONLY );
if( src_file < 0 )
{
printf( "Son: Error open file %s!!!\n", argv[1] );
exit(3);
}
printf( "Son: File %s is open!!!\n", argv[1] );
/* Чтение текстового файла и запись в канал */
close( file_ds[0] );
while( read(src_file, buf, 1) == 1 )
{
if( write( file_ds[1], buf,1 ) != 1 )
{
printf( "Son: error write to pipe!!!\n" );
break;
}
}
/* Закрытие дескрипторов */
close( src_file );
close( file_ds[1] );
return EXIT_SUCCESS;
}
default:
break;
}
/* Открываем файл для вывода */
dst_file = open( argv[2], O_WRONLY );
if( dst_file == -1 )
{
printf( "Father: Error open file %s!!!\n", argv[2] );
exit(4);
}
printf( "Father: File %s is open!!!\n", argv[2] );
/* Чтение из канала и вывод в файл */
// Нужно закрыть канал для записи, иначе чтение не завершится
close( file_ds[1] );
while( read(file_ds[0], buf, 1) == 1 )
{
write(dst_file, buf, 1);
}
/* Закрытие дескрипторов */
close( file_ds[0] );
close( dst_file );
return EXIT_SUCCESS;
}
В процессе-родителе создается неименованный канал, посредством системного вызова pipe(2), дочерние процессы получают доступ к дескрипторам созданного канала.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.