IPC микроядра на примере QNX Neutrino. Передача сообщений (функции send, receive, reply), страница 6

} else{

printf("Get system pulse\n");

if( pulse.code == _PULSE_CODE_DISCONNECT )

printf("Client disconnect\n");

}

}//end while(1)

name_detach(attach, 0);

return 0;

}

Результаты:

#

# ./th

Get Pulse 1 : value = 21

Get Pulse 2 : value = 8

#

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

1.2  передача пульса из обработчика прерывания

client:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <errno.h>

#include <sys/neutrino.h>

#include <sys/iomsg.h>

#include <hw/inout.h>

#define PATH "channel_pulse_int2"

int srv_coid;

int cnt = 0;

int seconds = 0;

int key_code;

int klav_exit = 0;

struct sigevent secpas;

const struct sigevent *timer_handler( void* area, int id)

{

cnt++;

if (cnt == 1000) {

cnt = 0;

seconds++;

return(&secpas);

}

else

return(NULL);

}

int main( int argc, char **argv)

{

int id;

int i;

if ((srv_coid = name_open(PATH, 0)) == -1) {

printf("Client name_open error\n" );

exit( EXIT_FAILURE );

}

ThreadCtl(_NTO_TCTL_IO, NULL);

secpas.sigev_notify = SIGEV_INTR;

id = InterruptAttach( 0, &timer_handler, NULL, NULL, 0);

for (i = 0; i < 5; i++) {

InterruptWait(0, NULL);

//printf("%d seconds left\n", seconds);

MsgSendPulse(srv_coid, 10, 1, seconds);

//fflush(stdout);

}

InterruptDetach(id);

if (ConnectDetach(srv_coid) == -1) {

fprintf(stderr, "%s: warning: in ConnectDetach(): %s\n", argv[0], strerror(errno));

}

return 0;

}

Server

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <errno.h>

#include <sys/neutrino.h>

#include <sys/iomsg.h>

#include <sys/iofunc.h>

#include <sys/dispatch.h>

#define PATH "channel_pulse_int2"

int main( int argc, char **argv)

{

int rcvid;

struct _pulse pulse;

struct _msg_info info;

name_attach_t *attach;

int chid;

if ( (attach = name_attach( NULL, PATH, 0 )) == NULL)

{

printf("server: can't attach name, errno %d\n", errno );

exit(1);

}

while(1) {

rcvid = MsgReceivePulse( attach->chid, &pulse, sizeof(pulse), &info);

printf("received value %d\n", pulse.value.sival_int);

if (pulse.value.sival_int == 5)

break;

}

return 0;

}

Результаты:

# gcc server.c -o server

# gcc client.c -o client

# ./server&

[1] 2637873

# ./client

received value 1

received value 2

received value 3

received value 4

received value 5

[1] + Done                 ./server

#

Каждую секунду отправляется пульс, его принимает сервер.

1.3  Передача сообщений с использованием файловой модели

(функции open, read, write)

Write.c

#include <sys/types.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

int

main (int argc, char* argv[])

{

int     file;

char buffer[] = {"Message\n"};

file = creat (argv[1], 666);

write (file,buffer ,sizeof(buffer));

close (file);

return (EXIT_SUCCESS);

}

Read.c

#include <sys/types.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

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

{

int file;

int size_read;

char buffer[100];

file = open(argv[1], O_RDONLY );

size_read = read( file, buffer, sizeof( buffer ) );

if( size_read == -1 )

{

printf( "Error reading %s", argv[1] );

return EXIT_FAILURE;

}

close( file );

printf ("%s", buffer);

return EXIT_SUCCESS;

}

Результаты:

# cd /home/IPC2/ReadWrite

# gcc write.c -o write

# gcc read.c -o read

# ./write /home/IPC2/ReadWrite/log.txt

# ./read /home/IPC2/ReadWrite/log.txt

Message

#

Сначала программа Write записывает сообщение в файл, затем программа read его читает оттуда.