Сигналы. Сетевая доставка сигналов. Системный вызов. Отправка сигнала процессу на удаленном узле. Программа приема сигнала, страница 7

if( argc < 2 ) {

printf( "Client: cmd args error!\n" );

exit(1);

}

unsigned int flag;

if( strcmp(argv[1],"-l" ) == 0 )       flag = 0;

else if( strcmp(argv[1],"-g" ) == 0 )  flag = NAME_FLAG_ATTACH_GLOBAL;

else {

printf( "Client: cmd args error!\n" );

exit(1);

}

// Отключаем буферизацию вывода //

setbuf( stdout, NULL );

// Открытие канала //

connect_id = name_open( ATTACH_POINT, flag );

if( connect_id == -1 ) {

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

exit(1);

}

printf( "Client: started. PID=%d.\n", getpid() );

signal( SIGINT, Sigint_Handler );

Setup_Timer( );

while(1)

{

printf( "Message: ");

scanf( "%s", send_buff.msg_buff );

if ( MsgSend( connect_id, &send_buff, sizeof(send_buff), &reply_buff, sizeof(reply_buff) ) == -1 ) {

printf( "Client: send msg error!\n" );

break;

}

printf( "Server reply message: %s \n", reply_buff.msg_buff );

fflush( stdout );

}

// Закрытие канала //

name_close( connect_id );

return EXIT_SUCCESS;

}

// Обработчик SIGINT //

void Sigint_Handler( int signo )

{

// Закрытие локального канала //

name_close( connect_id );

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

exit(0);

}

// Настройка таймера //

void Setup_Timer( )

{

timer_t timer_id;

struct sigevent timer_event;

struct itimerspec timer;

SIGEV_PULSE_INIT( &timer_event, connect_id, SIGEV_PULSE_PRIO_INHERIT, CODE_TIMER, 0 );

if( timer_create( CLOCK_REALTIME, &timer_event, &timer_id ) == -1 )

{

printf( "Client: Timer_create error.\n" );

}

timer.it_value.tv_sec = 5;

timer.it_value.tv_nsec = 0;

timer.it_interval.tv_sec = 5;

timer.it_interval.tv_nsec = 0;

timer_settime( timer_id, 0, &timer, NULL );

}

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

Локальный вариант.

Сервер

Клиент

Server: started.

PID=3199015, ND=0. Recieved Message: hi!

PID=3199015, ND=0. Recieved Message: 666

Recieved pulse from Timer: 00:12:38.

Recieved pulse from Timer: 00:12:43.

PID=3199015, ND=0. Recieved Message: 123

Recieved pulse from Timer: 00:12:48.

Client: started. PID=3199015.

Message: hi!

Server reply message: OK!

Message: 666

Server reply message: OK!

Message: 123

Server reply message: OK!

Message:

При запуске программы по сети пульсы по таймеру не передаются.

Timeline и Tracelog работы программы.   



Результат аналогичен предыдущей программе. Не смотря на то что прием пульса осуществляется с помощью MsgReceive(), вызывается функция ядра Receive Pulse.

4. Посылка пульса по прерыванию от клавиатуры.

Схема программы:


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

Программа сервер здесь используется из пункта 2.3.

Листинг 4.1. 2_4_pulse_and_kbdisr_client.c.

#define IRQ1_KBD    1

#include <stdio.h>

#include <sys/neutrino.h>

#include <sys/syspage.h>

#include <time.h>

#include <hw/inout.h>

#include <sys/dispatch.h>

const struct sigevent *kbdIsr( void *area, int id );

#define ATTACH_POINT      "qnx_msg_server"

#define CODE_KBD_ISR      2

#define IRQ1_KBD          1

struct sigevent kbdEvent;

volatile unsigned char keyNum;

struct _pulse pulse_msg;

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

{

int          channel_id,

sconnect_id,

connect_id,

rcv_id,

snd_id,

kbdIsr_id,

flag;

// Проверка командных опций программы //

if( argc < 2 ) {