Você está na página 1de 134

( 9-05-2008)

..............................................................................................................................................3
................................................................4
1 .............6
1.1 ....................................................................................................................6
1.2 ................................................................................................................... 7
1.3 ................................................................................................................... 8
1-30 1...10
2 ...... 12
2.1 ..................................................................................................................12
2.2 ..................................................................................................................12
2.3 ..................................................................................................................13
2.4 ..................................................................................................................13
2.5 ..................................................................................................................13
2.6 ..................................................................................................................14
2.7 ..................................................................................................................14
2.8 ..................................................................................................................15
2.9 ..................................................................................................................15
1-30 2...17
3
.................................................................................................................... 19
3.1 ..................................................................................................................19
1-3 3..20
3.2 ..................................................................................................................20
3.3 ..................................................................................................................20
12-14 3.20
3.4 ..................................................................................................................21
3.5 ..................................................................................................................21
15-20 3.23
3.6 ..................................................................................................................23
25-30 3....25
4-11 326
4 ,
................... 27
4.1. ................................................................................................................27
1-30 4....29
1. QNX Momentics
............................................................................................................................................ 30
2. 1
( ) .................................................................................................... 39
3. 2
( ) ............................................................................................................................. 54
4. 3
( /) .......................................................................................... 82
5. 4
( ) .................................................................................................................................. 126
........................................................................................... 134
.. 2008. . .

()

(). . :
- ( ) /
,
.

, ;
- ;
- ,
.
,
( ).
QNX Momentics
QSS (http://www.qnx.com). :
- , Neutrino

, ;
- API POSIX, , POSIX- .
, , QNX Momentics.



QNX Momentics.
QNX, (Vmware, Virtual PC ..), .. .
Photon.
IDE Momentics. , (10).
,
, .
,
.
, C QNX Neutrino
( _r), . , .

,
.
Safety .

(. errno,perror(), strerror(), assert()).
C
-. . ,
, :
MS Windows
MS Word;
Word-
Unicode UTF8 (,
pedit Photon QNX);
QNX .

.
. 9 2.1 ( 9: .5-2; .6-2; .7-2; .8-1; .9-3)
2.1

. 5

. 6

. 7

. 8

. 9

fork()

[ (.5)] --. fork() [ (.6)] ,


.
. ,
[
, ,
(.7)]. , [
(.8)]. : parent,
daugter grandchild.
. . ,
,
RR. 10
. RR ,
.
[ (.9)],
,
.
-.

1.1
( -> -> )
parent1
( - localtime(),
strftime()), pid, ,
, .
(.1).
parent2 .

pid. () ,
main(), 2 . -
2. daughter 1
daughter 2 1 2 (, 0 -). N 0.
1 N 1, 2 1.

(. 3 4).
30 sleep().
- , N, Photon pidin sin . ,
? pidin .
, N , .
, ,
.

. N. N
? .

1.2
( -> -> ->-)
parent1
( - localtime(),
strftime()), pid,
parent2, ,
.
(.1). pid.

daughter .
2 - grandchild1 grandchild2
(. 2) 50
. - 1 (1 ) 1 (2
)
N 0.
(. 3 4).
, N, .
.
, - N, Photon pidin sin
. ,
? pidin . .
N. N
? .

1.3
( -> ->
-> )
parent1
( - localtime(),
strftime()), pid, (. 2). (. 1) ,
, . parent2 , pid,
daughter1 daughter2
(. 2), 45 . N 0: N 1, .
(. 3 4). , , , N,
. ,
, .
, -
N,
Photon pidin . ,
?
pidin
. .
N. N
? .
1


1.
spawnl()
2.
spawnlp()
3.
spawnv()
4.
spawnvp()

/
/
/
/
1.
2.
3.
4.
5.
6.

10
10
10
9
10
9

10
10
9
10
10
10

RR
RR
FIFO
FIFO
FIFO
FIFO

RR
FIFO
RR
RR
FIFO
FIFO

3

( sched_yield())

1.
2.
3.

/ 1

/ 2

N

N 10000

1.

2.
3.

/ 1

/ 2

N 11000 ( RR->FIFO
FIFO->RR): N>0 1, N<0 2 .
.
N 11000 : N>0 1 +1, N<0
2 -1.
.

10

1-30
1

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.

11.
12.
13.
14.
15.
16.
17.
18.
19.
20.

1-10
1.1
. 1

. 2

. 3

. 4

1
3
2
4
3
4
1
2
3
4

6
5
4
3
2
1
3
5
2
4

1
2
3
3
3
2
1
1
2
3

3
3
1
2
1
3
3
3
3
1

11-20
1.2
. 1

. 2

. 3

. 4

4
4
3
3
1
1
2
2
2
4

3
6
1
4
2
5
1
2
3
4

3
2
3
1
3
2
1
1
3
3

1
3
3
3
1
3
3
3
3
2

11

21.
22.
23.
24.
25.
26.
27.
28.
29.
30.

21-30
1.3
. 1

. 2

. 3

. 4

4
1
2
3
2
1
3
4
1
2

1
2
6
5
4
3
2
6
4
1

3
3
2
1
3
1
1
3
3
2

3
2
3
3
1
3
3
1
3
3

12

2.1
( )
(.5) --. (.6)
, . . , ,
(.7).
, (.8). :
parent,
daugter grandchild. .
. , , RR. 10 .
RR ,
. (.9), , .
. .

2.2
( )
- main() N 64- uint64_t , 0.
30 ,

13

. while(1) {}. (incrementor) +1


N ,
UNIX 01.01.1970,
N (
time()). (supervisor) , N
, N
. (decrementor) N N
-1 . 1 N,
, - . .

2.3
( )
2.2, supervisor
incrementor, decrementor.

2.4
( )
2.2 , . 6. N ,
.

2.5
( )
2.3 , . 6. N ,
.

14

2.6
( -)
- - ,
.
delay(T), T , rand_r()
T = rand_r() % D,
2000 -,
D =
6000 -.
D 3 . -
60 , 1 2.
60 3.
- .
- RR

(.9) . .
- (read-write lock). 65 , .

2.7
( -)
2.4, .

15

2.8
( -, )
1 () 1000
. 3 -. ,
.
1000 ,
.9. , .
. , ,
,
. . 9. ispunct(), isdigit(), isalpha().

2.9
( -, )
2.6, . ,
.
5

1.
2.

16

1.
2.
3.

pthread_create()
fork()
spawnv()
7

1.
2.

1.
2.
3.
4.

1.
2.
3.
4.
5.
6.


(condition variable)
/ (read-write lock)
(sleepon lock)

17

1-30
2

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.

1-10
2.1
. 5

. 6

11-16
2.3

- 2.2

1
11.
12.
13.
14.
15.
16.


17.
18.
19.
20.
21.

. 7

. 8

. 9

1
2
4
1
2
1
3
4
1
3

1
2
3
2
1
1
2
3
3
1

2.4

2.5

. 6

1
17-22
2.6

2
3
-

3
2

2.7
. 9

2
3
1

1
2
-

18

22.

3
23-30

23.
24.
25.
26.
27.
28.
29.
30.

2.8

2.9

. 9


-
-

1
5
3
4
1
4
2
4
6
5
3
5
2
5
6
4

19

3.1
( POSIX, )
-
, a, o, t.
, - N=20. ,
t ,
. t 200 , delay().
-
,
.
-
, t

t = t*(N/N),

( ), , ( ).
. POSIX, .
:
1)
, - , ,
; 2) ; 3)
(. 9)
( ).

20

3.2
( POSIX)
3.1, .
1-3
3

1.
2.
3.

3.1

3.2
. 9

1
2
-

3.3
(, QNX Neutrino)

(Eratosthene, Eratosthenes, Erasmus, 276-194 . ..) . .
2 .


. ,
. . 0, , , .
, ,
.

21

, ,
( 4-11) 10.

3.4
( QNX Neutrino. 3.1)

. 5 t p. 4 . (.11) -.
, - .
11
12-14
3



12.
13.
14.


QNX Neutrino
QNX Neutrino
SIGRTMAX

3.5
(, QNX Neutrino)
mat1
mat2 m , n n , p (m 9, n 9, p 9)
mat
{ = mat
{1 * mat
1
2
32
m, p

m ,n

n, p

mat1 mat2 -10


+10.
mat i, j i- mat1 j- mat2 ( 0)

22
n 1

mat i , j = mat1i , k * mat 2 k , j


k = 0 1442443

(*)

Sk

mati,j , i mat1 j mat2. ,


, . -
(.12) -, mat,
.
(.13) main, .
12

1.
QNX Neutrino / ,
.

/ 2.
SIGRTMIN
.
,

3.
. QNX Neutrino (., ,
name_attach())
13
mat main

1.


QNX Neutrino,
main ( MsgDeliverEvent())

23

2.

QNX Neutrino,
main ,
-
15-20
3

15.
16.
17.
18.
19.
20.

15 - 20
3.5
12
1
1
2
2
3
3

13
1
2
1
2
1
2

3.6
(, QNX Neutrino)
3.5 ( ) . -

POSIX, -.
-, , , -, .
i mat1 j mat2 . mat .12. , -, .14.
mat
.13.

24

14

1.

2.

name_attach() name_open()
21-30
3

21.
22.
23.
24.
25.
26.
27.
28.
29.
30.

21 - 30
3.6
12
2
3
1
2

13
2
1
2
1
1
2
2
2
1
2

14
1
2
2
2
1
2
1
2
1
2

.10
4-11 3

( 3.3 - )
4 -11

5.

6.
7.

MsgSend()

, value

MsgSendPulse()

SIGUSR1
,
value
pthread_kill()

SignalKill()
SIGSPECIALMAX
,
value

MsgReceive()

sigwaitinfo()


- , (),
(. MsgDeliverEvent). (chid)
c .
-,
.
- -
.
(tid), . -
tid=1,
tid=2, 3, .
tid

25

4.

9.

11.

, value

MsgSend()

MsgSendPulse()

SIGUSR1
,
value
SignalKill()

SIGSPECIALMAX
,
value

MsgReceive()

26

10.

8.

tid+1 .
-
spawn*()) ,
(), (. MsgDeliverEvent).
(chid)
. -,
.

sigwaitinfo()

27

4
,

4.1.
( )
1.1, 1.2,
1.3 :
1. , (
-),
, N
13.57 , . .
.15. ()
( joinable). - .
2.
()
(. 16),
SIGEV_UNBLOCK.

pthread_join() . , pthread_join() ( ETIMEDOUT), pthread_join() timeout elapsed


pthread_join() . pthread_join() ( EOK), pthread_join() returned successfully.
3.
:
1) clock_gettime().
2) ClockCycles().
3) getrusage().

,
. -

28

, ,
. , . ,
time.
1-30
4

15
, -
1.*


1, 2, 3
-

10, 11, 12,


SIGUSR1
26, 27, 28
SIGALRM

SIGUSR2
timer_create()
4, 5, 6
timer_settime() -3
16, 17, 18,
-

19, 29, 30
-
SIGALRM
20, 21, 22
-5
7, 8, 9
TimerAlarm()
SIGALRM 13, 14, 15
setitimer()

23, 24, 25
delay()
-

29

1.1

1.2

1.3

16
,
pthread_join()
.
1) 20 ( ,
), 2) 10 - .
.
1) 18.05 ( ,
), 2) 6.33 - .
.
1) 15.78 (
, ), 2) 12.95 -
.

30

1.
QNX Momentics


UNIX- ,
, #
root $ .
. ,
myprog.out ,
$./myprog.out.
,
SIGINT (Ctrl-C) SIGQUIT
(Ctrl-\) - , .
,
$slay _ ( SIGTERM).

.

$kill SIGKILL pid ( #kill 9 pid. 9 -


SIGKILL), pid .
QNX ( . QNX Neutrino User's
Guide/Using the Photon microGUI/Hotkeys and shortcuts, pedit) :
Ctrl-Alt-1, Ctrl-Alt-2, Ctrl-Alt-3, Ctrl-Alt-4- 1,
2, 3, 4 (
4 );
Ctrl-C
( );
Ctrl-Alt-V
( pterm);
Ctrl-Alt-C
;
Ctrl-V ();
, - / ;

31

Ctrl-Alt-, Ctrl-Alt- - Photon;


Alt-F4 ;
Alt-Tab
.
FAT32 ( /) QNX. /fs hd0-dos*.
CD-
( - /fs/cd0), USB- (USB
Mass Storage Device). - FAT32- , (
):
#mount t dos /dev/hd0t11.1 /fs/hd3.
t dos
( dos, .. FAT32), /dev/hd0t11.1 , /fs/hd3 ,
QNX- ( ,
/fs). :
#mount t dos /dev/fd0 /fs/floppy.
NTFS QNX, .
, . 1.1. , QNX Momentics
. - , ,
summary (). , Utilities Summary ( ). .
. C. Summary of Functions.
, ( malloc(), calloc(),
realloc(), free()). (-

32

,
, , ..),

Memory fault (core dumped).
/var/dumps .core.
-
, ..
( 2) gdb ,
.
gcc (qcc gcc), ,
, .

core_dump_case.c .
QNX Momentics 6.3.2 SP3
,
,

( . ).

// core_dump_case.c
#include <stdlib.h>
#include <stdio.h>

/* //***
# gcc -ggdb core_dump_case.c -ocore_dump_case.out
# ./core_dump_case.out
//
Memory fault (core dumped)
//
# gdb core_dump_case.out /var/dumps/core_dump_case.out.core
GNU gdb 5.2.1qnx-nto
Copyright 2002 Free Software Foundation, Inc.

33

int main( void )


{
int *foo, *p, i;
//foo = (int *)malloc(10*4);
//***
for (p = foo, i = 12; i > 0; p++, i--) *p = i;
for (i = 12; i > 0; foo++, i--) printf("%d ", *foo);
printf("\n");
free(foo);
}

*/
/* //***
# gcc -ggdb core_dump_case.c -ocore_dump_case.out
# ./core_dump_case.out
12 11 10 9 8 7 6 5 4 3 2 1
//
Memory fault (core dumped)
//
# gdb core_dump_case.out /var/dumps/core_dump_case.out.core
GNU gdb 5.2.1qnx-nto
Copyright 2002 Free Software Foundation, Inc.

34


This GDB was configured as "ntox86"...
Program terminated with signal 11, Segmentation fault. //
- ( SIGSEGV =
11)
Reading symbols from /usr/qnx630/target/qnx6/x86/lib/libc.so.2...done.
Loaded symbols for /usr/qnx630/target/qnx6/x86/lib/libc.so.2
#0 0x0804849e in main () at core_dump_case.c:8
8
for (p = foo, i = 12; i > 0; p++, i--) *p = i; /*
, - */
(gdb)quit //
#

35


This GDB was configured as "ntox86"...
Program terminated with signal 11, Segmentation fault. //
- ( SIGSEGV =
11)
Reading symbols from /usr/qnx630/target/qnx6/x86/lib/libc.so.2...done.
Loaded symbols for /usr/qnx630/target/qnx6/x86/lib/libc.so.2
#0 0xb0320ce7 in __flist_dequeue_bin () from // - libc.so.2,
/usr/qnx630/target/qnx6/x86/lib/libc.so.2
//
(gdb) bt /* bt ,
, */
#0 0xb0320ce7 in __flist_dequeue_bin () from
/usr/qnx630/target/qnx6/x86/lib/libc.so.2
#1 0xb0320791 in _list_release () from
/usr/qnx630/target/qnx6/x86/lib/libc.so.2
#2 0xb0320f41 in __prelocked_free () from
/usr/qnx630/target/qnx6/x86/lib/libc.so.2
#3 0xb0320ff0 in __free () from /usr/qnx630/target/qnx6/x86/lib/libc.so.2
#4 0xb031ea4e in free () from /usr/qnx630/target/qnx6/x86/lib/libc.so.2
/* , free() main() ( 11 ) */
#5 0x08048578 in main () at core_dump_case.c:11
(gdb)quit //
# */

1.1
QNX

cd
chkfsys
clear

find

grep

. cd
DOS/Windows. , UNIX / : cd /home/mydir mydir, /home
qnx4 c .
. #chkfsys m /dev/hd0t79; #chkfsys rs /

. : #df -P. qnx4 /dev/hd0t79 ( hd0t77 hd0t78)
. grep
.
. (*.html) ,
( Examples)
/home/mydir/examples.txt:
#cd /usr/help/product/neutrino_2.11_en/lib_ref
#find . name *.html | xargs grep s F Examples > /home/mydir/examples.txt
.
. examples.txt
( sem, )
sem_examp.txt:
#grep s F sem /home/mydir/examples.txt > /home/mydir/sem_examp.txt

36

df

ls
more

mount

umount

passwd

pidin

37

on

. dir DOS/Windows.
: ls /home/mydir
. DOS/Windows.
: #pidin | more
, /.
. FAT,
/fs/floppy: #mount t dos /dev/fd0 /fs/floppy.
QNX 6.3.0 USB- .
. io-usb.
.
: umount /fs/floppy
/
.
. myprog.out, /home/mydir, 15 FIFO: #on p15f /home/mydir/myprog.out
.
. #passwd _ ;
#passwd __ ( root)
.
: #pidin ;
#pidin p 1716269 pid = 1716269 ;
#pidin | grep myprog myprog ;
#pidin arg | grep devc-ser8250 , devc-ser8250

pwd

qcc,
QCC

sin

su

38

gcc

, .
QNX- - .
. C,
myprog.c , myprog.out:
#qcc myprog.c o myprog.out;
, C++ : QCC myprog.cpp o myprog.out.
, (, sin(x)):
#qcc myprog.c omyprog.out l /lib/libm.a. l libm.a.
GNU-. , QNX , , qcc, .
. , (,
sin(x)): #gcc myprog.c omyprog.out -Ldir /lib/libm.a.
.
: #sin;
#sin P myprog th myprog;
#sin P io-graphics args , io-graphics
.
: $su root .

2.
1
( )
2.1
C QNX Neutrino

spawnl()
spawnlp()
spawnvp()
exit()
system()
getpid()
getppid()
wait()
sched_getparam()
sched_setparam()






. . spawn*()

,


. . - wait*()

39

spawnv()

sched_getscheduler()
sched_setscheduler()

40



. (main()) getprio()
1 ,
. (main()) 1 , .
setprio()
getprio() setprio() - .

sched_yield()
READY
pthread_create()
()
pthread_attr_init()

/
pthread_attr_setdetachstate()

/ pthread_attr_setinheritsched()


pthread_attr_setschedpolicy() . PTHREAD_EXPLICIT_SCHED
pthread_attr_setinheritsched()
. pthread_attr_setschedparam() PTHREAD_EXPLICIT_SCHED
pthread_attr_setinheritsched()
pthread_getschedparam()


pthread_setschedparam()

pthread_exit()
pthread_setcancelstate()
pthread_setcanceltype()
pthread_testcancel()
pthread_cancel()
pthread_setname_np()
pthread_getname_np()


/
(/ )



QNX Neutrino Core OS 6.3.2.

open()
close()
dup()
dup2()
setbuf()
time()

/ /


,

. NULL,

( ,
UNIX 1 1970 .
00 00 00 -

41


C QNX Neutrino,
2.2

strftime()
localtime()
asctime()
sleep()
mmap()

UTC (.. ) )



. , .

42

43

. 13
RR, 40 . N
(. ) .
, pid
, - 9 FIFO.
- : 100 101,
. - - N 0, :
- N<= 0, 1 N 1 , N<15001. N=15000 2;
- N>0, 2 N 1 , N> -15001. N= -15000 1.
-, ,
- .
:
- , 14;
- . pid ;
- 19 RR;
- 35 .
- .
, 2.0
1 sin. 7
.

zad1_primer-prim_foutp_cancel.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sched.h>
#include <process.h>
#include <errno.h>
#include<fcntl.h>
#define STDOUT 1
int N = 0, stop=1;

{
int *number;
pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL);/*

:
*/
pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
//
number = (int*) arg;
printf("grandchild1 of primary process starts with tid %d number %d\n", pthread_self(),
*number);
/* N. stop
while(stop)

*/
{
if (N<=0) while (N<15001) ++N;
//printf("1: %d\n", N);

44

//-----------------------------------------------------------------------------------------------void* function_grandchild1( void* arg )


// -

sched_yield(); //
}
}

//-----------------------------------------------------------------------------------------------void* function_grandchild2( void* arg )


// -
{
int *number;

//-----------------------------------------------------------------------------------------------void* function_daughter()
//
{
pthread_attr_t attr;
struct sched_param param;
int grndchld1=100, grndchld2=101; //
void* arg;

45

pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL);


pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
number = (int*) arg;
printf("grandchild2 of primary process starts with tid %d number %d\n", pthread_self(),
*number);
while(stop)
{
if (N>0) while (N> -15001) --N;
//printf("2: %d\n", N);
sched_yield();
}

int second_pid;
char buffer[15];
pthread_t gch1, gch2;

. Photon
. , - . ,
Photon shell 10, , FIFO (11) -. */
pthread_attr_setschedparam(&attr, &param);
pthread_attr_setschedpolicy(&attr, SCHED_FIFO); // FIFO
arg = (void*) &grndchld1;
pthread_create( &gch1, &attr, &function_grandchild1, arg );
arg = (void*) &grndchld2;

46

itoa(getpid(), buffer, 10); // pid -


printf( "This is thread %d of primary process\n", pthread_self() );
errno = EOK;
//
second_pid = spawnl( P_NOWAIT, "./zad1_primer-sec.out", "./zad1_primer-sec.out", buffer, NULL );
if(second_pid != -1) printf("Secondary process with pid %d launched\n", second_pid);
else
{
printf("Secondary process spawn error: %s\n", strerror( errno ));
exit(EXIT_FAILURE);
}
pthread_attr_init( &attr ); // -
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
param.sched_priority = 9; /* 11- -

pthread_create( &gch2, &attr, &function_grandchild2, arg );


second_pid = wait(NULL); //
printf("Daughter of the primary process: secondary process with pid %d stopped\n", second_pid);
pthread_cancel(gch1); // -
pthread_cancel(gch2);
//stop = 0; // -
}

//------------------------------------------------------------------------------------------------

int fptr, oldstdout;

/* output-prim.txt,
STDOUT. printf()
output-prim.txt. */

fptr = open("output-prim.txt",O_CREAT|O_RDWR,S_IREAD|S_IWRITE);
oldstdout = dup(STDOUT);
dup2(fptr,STDOUT);
close(fptr);
setbuf(stdout, NULL); //
time_of_day = time( NULL );
strftime( buffer, 80, " %A %B %d, %Y %H:%M:%S", localtime( &time_of_day ) );

// buffer ,

47

int main( void )


{
pthread_attr_t attr;
struct sched_param param;
time_t time_of_day;
char buffer[ 80 ];

printf( "Primary process with pid=%d starts at %s \n", getpid(), buffer );


pthread_attr_init( &attr );//
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
param.sched_priority = 13;
pthread_attr_setschedparam(&attr, &param); // 13
pthread_attr_setschedpolicy(&attr, SCHED_RR);// Round-Robin
pthread_create( NULL, &attr, &function_daughter, NULL );
sleep( 40 ); // 40 , -
time_of_day = time( NULL );
strftime( buffer, 80, " %A %B %d, %Y %H:%M:%S", localtime( &time_of_day ) );
printf("The primary process comes to the end at %s. N=%d\n", buffer, N);
//
return EXIT_SUCCESS;
48

zad1_primer-sec.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
//--------------------------------------------------------------------void* function( void* arg ) //
{
int policy;
struct sched_param param;
time_t time_of_day;
char buffer[ 80 ];

, sin, system() */
sleep(2);
}
return( 0 );
}

49

printf( "
This is thread %d of secondary process with pid %d\n", pthread_self(), getpid());
printf("\n
Output of sin utility:\n");
pthread_getschedparam(pthread_self(), &policy, &param);
while(param.sched_priority >=7)
{
param.sched_priority --; // 1
pthread_setschedparam(pthread_self(), policy, &param);
time_of_day = time( NULL );
printf("
Local time %s\n", asctime(localtime(&time_of_day)));
system("sin -P zad1_primer-sec th"); /* ,

int main(int argc, char **argv)


{
pthread_attr_t attr;
char buf[26];
time_t time_of_day;
struct sched_param param;

Round-Robin */
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
param.sched_priority = 19;
pthread_attr_setschedparam(&attr, &param);
pthread_attr_setschedpolicy(&attr, SCHED_RR);
pthread_create( NULL, &attr, &function, NULL );
sleep( 35 ); // 35
time_of_day = time( NULL );
ctime_r( &time_of_day, buf );
printf("
The secondary process with pid %d finished at %s\n", getpid(), buf);
return EXIT_SUCCESS;
}

50

setprio(getpid(), 14); // 14
setbuf(stdout, NULL); //
time_of_day = time( NULL );
ctime_r( &time_of_day, buf ); // buf
printf("
Secondary process with pid %d starts at %s My parent's pid=%d\n", getpid(), buf,
atoi(argv[1]));
/* 19
pthread_attr_init( &attr );

output_prim.txt
Primary process with pid=540708 starts at Thursday September 28, 2006 13:52:45
This is thread 2 of primary process
Seco
Secondary process with pid 544805 starts at Thu Sep 28 13:52:45 2006
My parent's pid=540708
This is thread 2 of secondary process with pid 544805
Output of sin utility:
Local time Thu Sep 28 13:52:45 2006
ndary process with pid 544805 launched

grandchild1 of primary process starts with tid 3 number 100


grandchild2 of primary process starts with tid 4 number 101
zad1_primer-sec.out
544805
4K
36K
12K
1 14r
NANOSLEEP
B0328E11
5
2 18r
REPLY
1 B0327A5D
0

648K

Local time Thu Sep 28 13:52:47 2006


zad1_primer-sec.out
1 14r
NANOSLEEP
2 17r
REPLY

544805
B0328E11
1 B0327A5D

4K

36K
5
1

12K

648K

4K

36K

12K

648K

Local time Thu Sep 28 13:52:50 2006


zad1_primer-sec.out

544805

51

. . - . .

1 14r
2 16r

NANOSLEEP
REPLY

B0328E11
1 B0327A5D

5
1

Local time Thu Sep 28 13:52:52 2006


zad1_primer-sec.out
1 14r
NANOSLEEP
2 15r
REPLY

544805
B0328E11
1 B0327A5D

4K

36K
5
1

12K

648K

4K

36K
5
1

12K

648K

4K

36K
5
1

12K

648K

4K

36K
5
1

12K

648K

4K

36K

12K

648K

Local time Thu Sep 28 13:52:54 2006


544805
B0328E11
1 B0327A5D

52

zad1_primer-sec.out
1 14r
NANOSLEEP
2 14r
REPLY

Local time Thu Sep 28 13:52:57 2006


zad1_primer-sec.out
1 14r
NANOSLEEP
2 13r
REPLY

544805
B0328E11
1 B0327A5D

Local time Thu Sep 28 13:52:59 2006


zad1_primer-sec.out
1 14r
NANOSLEEP
2 12r
REPLY

544805
B0328E11
1 B0327A5D

Local time Thu Sep 28 13:53:01 2006


zad1_primer-sec.out

544805

1 14r
2 11r

NANOSLEEP
REPLY

B0328E11
1 B0327A5D

5
2

Local time Thu Sep 28 13:53:04 2006


zad1_primer-sec.out
1 14r
NANOSLEEP
2 10r
REPLY

544805
B0328E11
1 B0327A5D

4K

36K
5
2

12K

648K

4K

36K
5
3

12K

648K

Local time Thu Sep 28 13:53:06 2006


544805
B0328E11
1 B0327A5D


7, , FIFO 9 - .
The secondary process with pid 544805 finished at Thu Sep 28 13:53:20 2006
Daughter of the primary process: secondary process with pid 544805 stopped
The primary process comes to the end at
Thursday September 28, 2006 13:53:25. N=5486

N -. N
,
pthread_cancel(gch1); pthread_cancel(gch2);


stop = 0;

53

zad1_primer-sec.out
1 14r
NANOSLEEP
2 9r
REPLY

3.
2
( )
C QNX Neutrino

3.1

pthread_mutexattr_init()
pthread_mutexattr_setpshared()

PTHREAD_MUTEX_INITIALIZER

pthread_mutex_lock()
pthread_mutex_unlock()
pthread_mutex_destroy()
sem_init()
sem_destroy()
sem_open()
sem_close()
sem_unlink()
sem_post()


/
,


(. )




/


1 ( )

54

pthread_mutex_init()

1 , 0

pthread_condattr_init()

/
pthread_condattr_setpshared()

,
pthread_cond_init()


PTHREAD_COND_INITIALIZER

pthread_cond_wait()
(. )
pthread_cond_signal()
,
pthread_cond_broadcast()
,
pthread_cond_destroy()

- pthread_rwlockattr_init()

/
pthread_rwlockattr_setpshared()
-
- pthread_rwlock_init()
,
pthread_rwlock_destroy()
-
pthread_rwlock_wrlock()
-
pthread_rwlock_rdlock()
-
pthread_rwlock_unlock()
-
sem_wait()

55


pthread_barrierattr_setpshared() /
, pthread_barrier_init()

pthread_barrier_destroy()

pthread_barrier_wait()

pthread_sleepon_lock()
,
pthread_sleepon_wait()

pthread_sleepon_signal()
,
pthread_sleepon_broadcast()
,
pthread_sleepon_unlock()

pthread_barrierattr_init()

56

#include
#include
#include
#include
#include
#include

<stdio.h>
<string.h>
<fcntl.h>
<sys/mman.h>
<semaphore.h>
<errno.h>

struct shared /* ,

mas, - sema /*

57

2.1. -
- fork(). - fork()
-, .
, first, second, third.
.
, , ,

RR. 10 .
RR , .
, , . - , , , ,
-. , .
.
-

sem_t sema;
char mas[360];
} shar;
struct shared *addr;

//---------------------------------------------------------------------word_write(char arg[]) /* ,
, */
{

//---------------------------------------------------------------------int main( int argc, char **argv )


{
pid_t pid, pid2;
//
int fd;
// /bolts
int n;
char *frst = "first", *sec = "second", *thrd = "third";/* ,

*/

58

int i, j, k, m;
strcat(addr->mas, " ");
for(i=0; i<strlen(arg); i++)
{
strncat(addr->mas, &arg[i], 1);
for(j=0; j<1000; j++)
for(k=0; k<1000; k++) m *= (k+j)/(k*j+1);
}

setbuf(stdout, NULL);
//
shm_unlink( "/bolts" );/* /bolts

, - . */
fd = shm_open( "/bolts", O_RDWR | O_CREAT, 0777 );
/* ( )
( -) /bolts */
ftruncate( fd, sizeof( shar ));/* /bolts
, */
addr = mmap(0,sizeof( shar ),PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);

pid = fork(); // ,
if( pid == 0 ) {
//
printf("child with pid %d\n", getpid());
pid2 = fork(); /* -, */
if (pid2 == 0) {
// -
printf("grandchild with pid %d\n", getpid());
for(n=0; n<10; n++)
{
while(sem_wait(&addr->sema)&& errno==EINTR);
word_write(thrd);

59

//
strcpy(addr->mas, "first"); /* "first" */
sem_init(&addr->sema, 1, 1);// 1 ( )
close( fd );
// -
shm_unlink( "/bolts" );/* . ,
*/

sem_post(&addr->sema);
}
printf("grandchild finishies\n");
}
else {
// ,
for(n=0; n<10; n++)
{
while(sem_wait(&addr->sema)&& errno==EINTR);
/*

word_write().
sem_wait()
, EINTR */
}
wait(NULL);
// -
printf("child finishies\n");
}
} else { ,
printf("parent with pid %d\n", getpid());
for(n=0; n<10; n++)
{
while(sem_wait(&addr->sema)&& errno==EINTR);
word_write(frst);
sem_post(&addr->sema);
}
wait(NULL);
//
printf("parent: shm= %s\n", addr->mas);

60

word_write(sec);
sem_post(&addr->sema);/* */

sem_destroy(&addr->sema); // .
printf("parent finishies\n");
}
}

. .
pcahrielndt wwiitthh ppiidd 786471782374

pcahrielndt

. .
wwiitthh ppiidd 827431823334

grandchild with pid 827432


grandchild finishies
child finishies
parent: shm= first f sierc tsohtni fdri sdre tschtio frniddr t sshtei
fcriodrn tsdht si fericdro tsnhtdi f sriedrc tsohtni fdri sdre tshctoi
fnriddr t sshetci forindrd ts shtei fcriodrn tsdhti sercdond second
parent finishies

61

grandchild with pid 786472


grandchild finishies
child finishies
parent: shm= first first second third first second third first second third
first second third first second third first second third first second third
first second third first second third first second third
parent finishies

62

2.2. - recorder1 recorder2 sensor1 sensor2, , . Recorder1 recorder2 , , .


sensor_read[2]. recorder1 recorder2 , .. . sensor_read collector. () 10 .
, , logger logger.dat
.
, :
- sensor_read .
recorder1, recorder2 collector ;
- :
- sensor_read (, recorder1), - (recorder2);
- sensor_read
collector. , -,
.

- collector logger.
. Collector
, logger .
#include
#include
#include
#include
#include
#include

<stdio.h>
<pthread.h>
<inttypes.h>
<fcntl.h>
<errno.h>
<sys/mman.h>
63

pthread_mutex_t mtx1 = PTHREAD_MUTEX_INITIALIZER; //


pthread_cond_t cv1 = PTHREAD_COND_INITIALIZER;
//
pthread_mutex_t mtx2 = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cv2 = PTHREAD_COND_INITIALIZER;
pthread_barrier_t barrier;
int sensor_1, sensor_2;
int sensor_read[2];
unsigned int seed1, seed2, seed3, seed4;// .
int is_data = 0; // 00 01 10 11
int data_logged = 1; // 0-data are not written to file, 1-data are written
to file
int mean1, variance1, mean2, variance2, delta1, delta2; /*
*/
//----------------------------------------------------------------------------void *sensor1()// - . sensor_1

printf("sensor1 starts\n");
while(1)
{
usleep(100000);
sensor_1 = rand_r(&seed3) / 100;
//printf("*%d ", sensor_1);
}

64

}
//----------------------------------------------------------------------------void *sensor2()// - . sensor_2
{
printf("sensor2 starts\n");
while(1)
{
sensor_2 = rand_r(&seed4) / 100;
//printf("**%d ", sensor_2);
usleep(100000);
}
}
//----------------------------------------------------------------------------void *recorder1() // -
{
pthread_barrier_wait(&barrier); //
printf("recorder1 starts\n");
while(1)

{
pthread_mutex_lock (&mtx1);

/* is_data sensor_read */

65

while (is_data ==1 || is_data == 3) pthread_cond_wait (&cv1,&mtx1);


// is_data cv1
/* - is_data:
0- sensor_read ;
1- sensor_read 1- ;
2- sensor_read 2- ;
3- sensor_read . . */
usleep(rand_r(&seed1)*100);
// 1
sensor_read[0]=sensor_1; // 1
printf(" \nrecorder1 %d\n", sensor_read[0]);
if (is_data ==0||is_data ==2) is_data += 1;// -
pthread_cond_broadcast (&cv1);/* cv1 , sensor_read is_data */
pthread_mutex_unlock(&mtx1); /* mtx1,
is_data
sensor_read */
}
}
//----------------------------------------------------------------------------void *recorder2() // -

66

pthread_barrier_wait(&barrier); //
printf("recorder2 starts\n");
while(1)
{
pthread_mutex_lock (&mtx1);
while (is_data ==2 || is_data == 3) pthread_cond_wait (&cv1,
&mtx1);
usleep(rand_r(&seed2)*79);
sensor_read[1] = sensor_2;
printf(" \nrecorder2 %d\n", sensor_read[1]);
if (is_data ==0 || is_data ==1) is_data += 2;
pthread_cond_broadcast (&cv1);
pthread_mutex_unlock(&mtx1);
}
}
//----------------------------------------------------------------------------void * collector ()
//-
{
int n;
printf ("collector starts\n");
while(1)
{
pthread_mutex_lock (&mtx2); /*
, logger */
while (!data_logged) pthread_cond_wait (&cv2, &mtx2);/* -

67

cv2, logger
data_logged 1 */
mean1=variance1=mean2=variance2=0;/*
*/
for(n=1; n<=10; n++)
{
pthread_mutex_lock (&mtx1);
while (is_data < 3 ) pthread_cond_wait (&cv1, &mtx1);
// process data
printf ("--collector: %d %d %d\n", n, sensor_read[0],
sensor_read[1]);
delta1 = sensor_read[0] - mean1;
delta2 = sensor_read[1] - mean2;
mean1 = mean1 + delta1 / n;
mean2 = mean2 + delta2 / n;
variance1= variance1 + delta1*(sensor_read[0]-mean1);
variance2= variance2 + delta2*(sensor_read[1]-mean2);
sensor_read[0] = sensor_read[1] = is_data = 0;
pthread_cond_broadcast (&cv1);
pthread_mutex_unlock (&mtx1);
}
variance1= variance1 / (10-1);
variance2= variance2 / (10-1);
printf("Collector: mean1=%d mean2=%d variance1=%d
variance2=%d\n", mean1, mean2, variance1, variance2);
data_logged = 0;

pthread_cond_signal(&cv2); /* logger cv2,


*/
pthread_mutex_unlock (&mtx2); /* ,
logger . data_logged */

printf("logger starts\n");
num_logs = *(int*) arg; /* - logger.dat.
*/
// POSIX- logger.dat
fd = open( "logger.dat", O_WRONLY | O_CREAT | O_APPEND | O_TRUNC |
O_SYNC, S_IRUSR | S_IWUSR );
//
//fd = creat( "logger.dat", S_IRUSR | S_IWUSR );//
sprintf(buffer, "#\tmean1\tmean2\tvar1\tvar2\t\tlog_time\n");

68

}
//----------------------------------------------------------------------------void *logger(arg)
//-
{
int num_logs;
int fd, j;
char buffer[100];
int len;
char log_time[26];
time_t time_of_day;
struct timespec * stop_time;

stop_time = (struct timespec *) mmap(0, sizeof(struct timespec),

69

write(fd, buffer, strlen(buffer));//


for(j = 0; j < num_logs; j++) /* .
*/
{
pthread_mutex_lock (&mtx2);//
while (data_logged) pthread_cond_wait (&cv2, &mtx2);/*
cv2 , . */
time_of_day = time( NULL );
//
ctime_r(&time_of_day, log_time);
sprintf(buffer, "#%d\t%d\t%d\t%d\t%d\t%s", j, mean1, mean2,
variance1, variance2, log_time);
printf("Logger: %s\n", buffer);
write(fd, buffer, strlen(buffer));// -
data_logged = 1;
strcpy( buffer, "");
pthread_cond_signal(&cv2); /* collector,
*/
pthread_mutex_unlock (&mtx2);/*
data_logged */
}
close(fd);// -

printf("main starts\n");
setbuf(stdout, NULL); //
seed1 = (unsigned int) time(NULL);//

70

PROT_READ | PROT_WRITE, MAP_ANON, NOFD, 0);/* malloc()/free(),


mmap()/munmap() */
clock_gettime( CLOCK_REALTIME, stop_time); /* , logger, */
pthread_exit((void*) stop_time); /* ,
( main), */
}
//----------------------------------------------------------------------------main ()
{
pthread_attr_t attr;
pthread_t snsr1, snsr2, rcrd1, rcrd2, lggr;
int fd;
char read_line[100];
char buf;
struct timespec *logger_end_time = NULL;
long long sec;
long nsec;
uint64_t current_time;
int num_logs = 3;

seed3 = 1234;
seed4 = 4321;

ClockTime_r( CLOCK_REALTIME, NULL, &current_time);//


printf("Current system time=%lld ns\n", (long long) current_time);

71

pthread_barrier_init( &barrier, NULL, 2);/* 2


*/
pthread_attr_init( &attr );
pthread_attr_setschedpolicy( &attr, SCHED_FIFO); /*
FIFO - */
pthread_create (&snsr1, &attr, sensor1, NULL);
pthread_create (&snsr2, &attr, sensor2, NULL);
pthread_create (&rcrd1, NULL, recorder1, NULL);
seed2 = (unsigned int) time(NULL); // f
pthread_create (&rcrd2, NULL, recorder2, NULL);
pthread_create (NULL, NULL, collector, NULL);
pthread_create (&lggr, NULL, logger, (void*) &num_logs);
pthread_join(lggr, (void**) &logger_end_time); /* ,
*/
pthread_cancel(snsr1); //
pthread_cancel(snsr2);
pthread_cancel(rcrd1);
pthread_cancel(rcrd2);

printf("Data logging stopped at %lld sec %ld nsec system time\n",


logger_end_time->tv_sec, logger_end_time->tv_nsec);
munmap((void *) logger_end_time, sizeof(struct timespec));/*
, */

2.6. ( , sensor())
,
sens[5]. .
- ( - re-

72

setvbuf(stdout, NULL, _IOFBF, 0);


//
fd = open( "logger.dat", O_RDONLY | O_SYNC, S_IRUSR | S_IWUSR );/*
logger.dat */
while (!eof(fd)) // logger.dat
while(1)
{
read(fd, &buf, sizeof(buf));
if (buf == '\n') {printf("\n"); break;}
else printf("%c", buf);
}
close(fd);
//unlink(fd); // logger.dat

#include <pthread.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#define el 5
#define repeat 15

// 5
// 15

unsigned sens[el]={0};
//
pthread_rwlock_t rwl;
pthread_barrier_t barrier_el, barrier_el2;

73

corder()) - (( - analyzer()). -
array_of_max, . -
( ,
- ).
15 . , ,
. () .
- , -: - (..) sens, - (.. )
,
.

int file_descriptor, mapped_fd;


static int *map_addr;
fpos_t pos;
pthread_t sens_thr[5], anlzr;

74

//-----------------------------------------------------------------------------------------------------stdout_to_file() /* stdout
logged_data.dat.
*/
{
fflush(stdout);
fgetpos(stdout, &pos);
file_descriptor = dup(fileno(stdout));
mapped_fd = fileno(freopen("logged_data.dat", "w", stdout));/*
logged_data.dat ,
stdout reopen()*/
map_addr = (int *) mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE,
mapped_fd, 0); // .
map_addr-
}
//-----------------------------------------------------------------------------------------------------file_to_stdout() /* stdout
logged_data.dat.
{
fflush(stdout);

dup2(file_descriptor, fileno(stdout));
close(file_descriptor);
clearerr(stdout);
fsetpos(stdout, &pos);
msync(map_addr, 1024, MS_SYNC);/*
*/
munmap(map_addr, 1024);//

75

}
//-----------------------------------------------------------------------------------------------------int compare( const void *op1, const void *op2 )
/* qsort()
lsearch()
{
const int *p1 = (const int*) op1;
const int *p2 = (const int*) op2;
//printf("---%d\n", *p1 - *p2);
return(*p1 - *p2);
}
//-----------------------------------------------------------------------------------------------------void *sensor()// , - ()
{
int i = pthread_self()-2;
static unsigned int seed = 1234;
printf("Sensor %d starts\n", i);
while(1)
{

}
//------------------------------------------------------------------------------------------------------

76

if(i==0) sleep(3); /* 3 . barrier_el


3 */
pthread_testcancel();//
pthread_barrier_wait(&barrier_el); /* - , 5
. tid 2,
3 .
*/
pthread_rwlock_wrlock(&rwl); // -
sens[i] = rand_r(&seed)/1000; // sens[]
// RAND_MAX=32767u
printf("%d ", sens[i]);
pthread_rwlock_unlock(&rwl); /* - .
- ,
*/
pthread_barrier_wait(&barrier_el2); /* -
,
, .. 7
5 -, 2 . ,
sens[] , ..
-
. ,
, */

void *recorder(void* arg) // , - ( 1)


{
int i, j, max;
int repetitions; //
unsigned num=0;
// array_of_max[]
int *array_of_max; /*
*/
printf("Recorder %d starts\n", pthread_self());
repetitions = *(int*) arg;

77

array_of_max = (int*)calloc(el*repeat, sizeof(int));


for( j=0; j <= repetitions; j++)
{
pthread_rwlock_rdlock(&rwl);// -
if(j>0)
{
printf("\n#%d\tRec->", j);
for(i=0; i<el; i++) printf("%d ", sens[i]);
max=sens[0];
for(i=1; i<el; i++) if(sens[i]>max) max=sens[i];
printf(" max=%d ", max);//
lsearch( &max, array_of_max, &num, sizeof(int), compare );
// array_of_max[],
printf("curr arr : ");

for( i = 0; i < num; i++ ) printf( "%d ", array_of_max[i]);


printf("\n"); // -

}
pthread_rwlock_unlock(&rwl); // -
pthread_barrier_wait(&barrier_el2);/* 5
, */

}
//-----------------------------------------------------------------------------------------------------void *analyzer() //, - ( 2)
{
char encrypted_array[64] = {0};
int i;

78

}
printf("\narray_of_max ");// 15
for( i = 0; i < num; i++) printf( "%d ", array_of_max[i]); printf("\n");
qsort(array_of_max, num, sizeof(int), compare); /*
*/
printf("sorted array_of_max ");
for( i = 0; i < num; i++ ) printf( "%d ", array_of_max[i]);
printf("\n");
free(array_of_max);
printf("recorder ****\n");
for(i=0; i<el; i++) pthread_cancel(sens_thr[i]);/*
- - */
pthread_cancel(anlzr);

static unsigned int seed = 2630;


static char __key[64];
static int count=0;
char buffer[80] = { "Data registration starts at " };
char time_buffer[30];
time_t time_of_day;

79

printf("Analyzer %d starts\n", pthread_self());


time_of_day = time(NULL);
strftime(time_buffer, 60, "%a %b %d, %Y %R:%S",
localtime( &time_of_day));
strcat(buffer, time_buffer);
printf("%s\n", buffer);
//
// 64-
for(i=0; i<64; i++) __key[i] = (rand_r(&seed) > RAND_MAX/2) ? 1:0;
setkey(__key );
while(1)
{
pthread_rwlock_rdlock(&rwl); /* - .
*/
if(count>0)// - ,
{
printf(" **anal : encrypted array -> ");
for(i=0; i<el; i++) encrypted_array[i] = sens[i];
encrypt(encrypted_array, 0);//
for(i=0; i<64; i++)

if(i<6) printf("%d ", encrypted_array[i]);


else printf("%d", encrypted_array[i]); printf("\n");
//
}
count++;
pthread_rwlock_unlock(&rwl); // -
pthread_barrier_wait(&barrier_el2); /* 5
, */
}

printf("main starts\n");
stdout_to_file(); /*
printf() */
setbuf(stdout, NULL);
pthread_rwlock_init(&rwl, NULL);
pthread_attr_init(&attr);
pthread_barrier_init(&barrier_el, NULL, el);

80

}
//-----------------------------------------------------------------------------------------------------main()
{
int i;
pthread_t rcrdr;
pthread_attr_t attr;
int rpt = repeat; // repeat 15 times reading of sensor series

81

pthread_barrier_init(&barrier_el2, NULL, el+2);


pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
attr.flags = attr.flags | PTHREAD_CANCEL_ENABLE |
PTHREAD_CANCEL_ASYNCHRONOUS; /*
FIFO */
for(i=0; i<el; i++) pthread_create( &sens[i], &attr, &sensor, NULL );
// -
pthread_create( &rcrdr, &attr, &recorder, (void*) &rpt);
pthread_create( &anlzr, &attr, &analyzer, NULL);/*
*/
pthread_join(rcrdr, NULL);
for(i=0; i<el; i++) pthread_join(sens[i], NULL );
pthread_join(anlzr, NULL);
printf("main *****\n");
file_to_stdout(); /* printf() ,
stdout_to_file().
stdout_to_file()*/
printf("main stops\n");

4.
3
( /)
. .4.1
C QNX Neutrino
POSIX

POSIX
POSIX


( )

POSIX
POSIX
POSIX



,

82

shm_open()
shm_unlink()
mmap()
munmap()
ftruncate()
shm_ctl()
mq_open()
mq_close()
mq_unlink()
mq_setattr()
mq_send()
mq_receive()
mq_notify()

3.1 3.2. . 5 t p, (t1,p1), (t2,p2), (t5, p5).


4 , POSIX. -
.
3. 3
. POSIX, - t
p 3.
83

// , POSIX
#include <mqueue.h>
#include <stdlib.h>
//-----------------------------------------------------------------------------------------------------------------------main()
{
mqd_t pmq;
struct { int t;
float p;
} pair; // -
int i;
char rcv_buf[4096];
int received;
unsigned int msg_prio;
struct mq_attr mqstat;

sigset_t set;
pid_t child_pid;
int status;

84

mq_unlink("/my_pmq"); /* /my_pmq,
( ) */
pmq = mq_open("/my_pmq", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR , NULL);
//
mq_getattr(pmq, &mqstat); /* :
printf(" reader:POSIX mq created with attributes%ld %ld %ld %ld %ld\n",
mqstat.mq_maxmsg, /* - ,
*/
mqstat.mq_msgsize,
//
mqstat.mq_curmsgs,
// -
mqstat.mq_sendwait,
// 0,
mqstat.mq_recvwait); // 0,
child_pid = spawnl( P_NOWAIT, "mq_sensors-3.out", "mq_sensors-3.out",
NULL); //
if(child_pid>0) printf(" reader: mq_sensors with pid=%d launched\n",
child_pid);// pid
for(i=0; i<15; i++)//
{
received = mq_receive( pmq, rcv_buf, 4096, NULL );
printf(" reader: received %d bytes = %s", received, rcv_buf);

85

}
mq_close(pmq);// ,
mq_unlink("/my_pmq");
printf(" reader: Killing %d ...\n", child_pid);
kill(child_pid, SIGUSR1);// , SIGUSR1
waitpid(child_pid, &status, WEXITED);/*
*/
printf(" reader: WIFSIGNALED returns %d WIFEXITED returns %d\n",
WIFSIGNALED(status), WIFEXITED(status));
if (WIFEXITED(status))
{
printf(" reader: Sensors terminated normally, exit status = %d\n",
WEXITSTATUS(status));
}
else if (WIFSIGNALED(status))
{
printf(" reader: Sensors terminated abnormally by signal = %X\n",
WTERMSIG(status));
}
}
//=========================================================================
// mq_sensors-3.c,
#include <stdio.h>
#include <pthread.h>
#include <mqueue.h>
#include <stdlib.h>

#include <limits.h>

86

mqd_t pmq;
pthread_barrier_t barrier;
//-----------------------------------------------------------------------------------------------------------------------void handler(signo)// - SIGUSR1
{
if(signo == SIGUSR1)
{
printf("snsrs: catched stop signal %d. Terminate\n", signo);
fflush(stdout);
_exit( EXIT_SUCCESS );
}
}
//-----------------------------------------------------------------------------------------------------------------------void* sensor(arg)// -
{
static unsigned int* seed;
char snd_buf[20], snd_bufs[20];
struct
{
int t;
float p;
} pair;
sigset_t set;
unsigned int prio;

printf("snsrs: sensor %d %d starts\n",


seed = (unsigned int*) arg;

getpid(), pthread_self());

}
//-----------------------------------------------------------------------------------------------------------------------main()

87

sigemptyset( &set );
sigaddset(&set, SIGALRM);
pthread_sigmask(SIG_SETMASK, &set, NULL);/*
SIGALRM, main() */
while(1)
{
pthread_barrier_wait( &barrier ); /* , main()
*/
pair.t = rand_r(seed) / 100;
pair.p = rand_r(seed) / 1000.0;
sprintf(snd_buf, "%d %d %.2f\n", pthread_self(), pair.t, pair.p);
printf("snsrs: %s", snd_buf);
if(pthread_self()== 4) prio = MQ_PRIO_MAX;
else prio = 20 - pthread_self();
mq_send(pmq, snd_buf, 20,prio);
/* .
20 - pthread_self(). 3
MQ_PRIO_MAX=32 (. limits.h) */
}

pmq = mq_open("/my_pmq", O_RDWR, S_IRUSR | S_IWUSR , NULL);/*


/ */
if(pmq > 0)
printf("snsrs: POSIX message queue with descriptor=%d opened\n", pmq);
else return EXIT_FAILURE;
sigemptyset( &set );
sigaddset(&set, SIGALRM);

88

pthread_t tid[5];
int seed[5] = {1234, 2143, 3412, 4321, 1423};/*
*/
pthread_attr_t attr;
int i;
char rcv_buf[4096];
//struct itimerval value; /* @ -
setitimer().
ualarm() @*/
sigset_t set;
int sig;
struct sigaction act;
pthread_barrier_init( &barrier, NULL, 6);
pthread_attr_init(&attr);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);

pthread_sigmask(SIG_SETMASK, &set, NULL);/* SIGALRM,


sigwait()*/
act.sa_flags = 0;
act.sa_mask = set;
act.sa_handler = &handler;
sigaction( SIGUSR1, &act, NULL );/*
SIGUSR1 */
/*

*/
ualarm(4000000, 4000000);/* 4 ,
4 */
printf("snsrs: interval timer launched\n");
for(i=0; i<5; i++) pthread_create(&tid[i], &attr, &sensor,
(void *) &seed[i]);
while(1)
{
sigwait(&set, &sig); /* SIGALRM ( 14 - . signal.h)
printf("snsrs: accepted signal %d\n", sig); fflush(stdout);
pthread_barrier_wait( &barrier );
}

89

value.it_value.tv_sec = 4;
value.it_value.tv_usec = 0;
value.it_interval.tv_sec = 4;
value.it_interval.tv_usec = 0;
setitimer ( ITIMER_REAL, &value, NULL);

}
. .4.2
C QNX Neutrino

/
( ) ( )



/ ( sigprocmask()
)
pthread_sigmask() / ( )
sigwait()

sigwaitinfo()

kill()

(.. , sigqueue()
)
SignalKill()
, , ..
pthread_kill()

3.5. ( 3.1, ).

90

sigaction()
sigemptyset()
sigaddset()
sigdelset()
sigfillset()

. 5 t p.
4 .
-. , -
.

91

// -,
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <process.h>
#include <sys/netmgr.h>
//-----------------------------------------------------------------------------------------------------------------------main()
{
pid_t child_pid;
int stat_loc;
sigset_t wait_set;
siginfo_t info;
int sensor, t;
float p;
extern void handler();
struct sigaction act_to_sensor;
sigset_t set;
int i, status;

printf("PARENT with pid %d started\n", getpid());


// SIGRTMAX, :
sigemptyset(&set); // set
act_to_sensor.sa_flags = SA_SIGINFO; //
act_to_sensor.sa_mask = set; /* ,
- */
act_to_sensor.sa_handler = NULL; /* - .
*/
sigaction( SIGRTMAX, &act_to_sensor, NULL );//

// -
child_pid= spawnl( P_NOWAIT,"sig_sensors2.out","sig_sensors2.out",NULL);
if(child_pid>0) printf("sensors with pid=%d launched\n", child_pid);
for(i=0; i<6*5; i++)
// 6
{
sigwaitinfo(&wait_set, &info);// SIGRTMAX
printf("
PARENT receive signal %d with value %d ",
info.si_signo, info.si_value);
// (value) :
sensor = info.si_value.sival_int % 10;

92

sigemptyset(&wait_set);
// , sigwaitinfo()
sigaddset(&wait_set, SIGRTMAX);

t = info.si_value.sival_int / 1000000;
p = (float) ((info.si_value.sival_int - sensor) % 1000000)/1000.0;
printf(" sensor=%d t=%d p=%.2f\n", sensor, t, p);
fflush(stdout);

SignalKill(ND_LOCAL_NODE,child_pid,0,SIGUSR1,SI_USER,12345);/*
SIGUSR1 SI_USER (=0 POSIX, . c SignalKill())
12345 ( )
*/
sigwaitinfo(&set, &info);/* SIGCHLD
*/
switch (info.si_signo) {
case SIGCHLD:
printf(" PARENT: received signal SIGCHLD. A child with pid=%d
terminated\n", info.si_pid);
break;
default:
}

93

// SIGCHLD :
sigemptyset( &set );
sigaddset(&set, SIGCHLD);
act_to_sensor.sa_flags = 0;
act_to_sensor.sa_mask = set;
act_to_sensor.sa_handler = NULL; &handler;
sigaction( SIGCHLD, &act_to_sensor, NULL );

wait(&status); //
if (WIFEXITED(status))
{
printf("
child terminated normally, exit status = %d\n",
WEXITSTATUS(status));
}
else if (WIFSIGNALED(status))
{
printf("
child terminated abnormally by signal = %X\n",
WTERMSIG(status));
}

//=========================================================================
// sig_sensors2.c,
-
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <math.h>

94

}
//-----------------------------------------------------------------------------------------------------------------------void handler(signo)/* - .
. */
{
}

95

//-----------------------------------------------------------------------------------------------------------------------// - SIGUSR1
void signal_handler(int signo, siginfo_t *info, void *extra)
{
printf("snsrs: Received termination signal %d with code %d
and value %d\n", info->si_signo, info->si_code,
info->si_value.sival_int);
_exit(EXIT_SUCCESS);
}
//-----------------------------------------------------------------------------------------------------------------------void* sensor(arg) //
{
static unsigned int* seed;
struct
{
int t;
float p;
} pair;
sigset_t set_for_sensor, mask;
static count=0;
char snd_buf[30];
siginfo_t info;
int s_pair;
int pid, ppid, tid;
int aux;

pid = getpid();
ppid = getppid();
tid = pthread_self();
printf("snsrs: sensor

// pid
// pid
// tid -
%d %d starts. PARENT pid is %d\n",

seed = (unsigned int*) arg;

pid, tid,
ppid);

sigfillset(&mask);
// , -
sigdelset(&mask, SIGALRM);// SIGALRM
pthread_sigmask(SIG_SETMASK, &mask, NULL);

while(1)
{
pthread_sigmask(SIG_UNBLOCK, &set_for_sensor, NULL);
/*
set_for_sensor , .. SIGALRM */
sigwaitinfo(&set_for_sensor, &info); // SIGALRM
if(info.si_code == SI_TIMER) printf("received signal %d from timer
with value %d\n", info.si_signo, info.si_value);
pthread_sigmask(SIG_BLOCK, &set_for_sensor, NULL); /*
set_for_sensor , .. SIGALRM
- */
pair.t = rand_r(seed) / 100; //

96

sigemptyset(&set_for_sensor);
// , -
sigaddset(&set_for_sensor, SIGALRM); // SIGALRM

}
//-----------------------------------------------------------------------------------------------------------------------main()

97

pair.p = rand_r(seed) / 1000.0;


sprintf(snd_buf, "%d %d %d %.2f ", count, tid, pair.t, pair.p);
printf("snsrs: %s\n", snd_buf);
fflush(stdout);
aux = (int) (pair.p*1000.0); /* ,
s_pair int SIGRTMAX*/
aux = aux - aux%10;
s_pair =pair.t*1000000 + aux +tid;
sigqueue ( ppid, SIGRTMAX, (union sigval) s_pair); /*
SIGRTMAX - */
if (count < 4) /* - .
- , SIGALRM,
,
*/
{
kill(pid, SIGALRM);
count++;
}
else
{
printf("\n");
count = 0;
}

pthread_attr_init(&attr); // -
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
/* SIGUSR1,
*/
sigdelset(&set, SIGUSR1);
act.sa_flags = 0;
act.sa_mask = set; /*
- */
act.sa_handler = &signal_handler; //
sigaction( SIGUSR1, &act, NULL );
sigfillset( &set );

98

pthread_t tid[5];
int seed[5] = {1234, 2143, 3412, 4321, 1423};
pthread_attr_t attr;
int i;
struct sigevent event;
struct itimerspec itime;
timer_t timer_id;
sigset_t set, set_for_main;
struct sigaction act;
int signal_value = pthread_self();
// 1
short signal_code = SI_TIMER;
// -1

. .4.3
C QNX Neutrino

99

sigemptyset(&set_for_main); /* main.
SIGALRM, -*/
sigaddset(&set_for_main, SIGALRM);
pthread_sigmask(SIG_SETMASK, &set_for_main, NULL);
/* , signal_code
= SI_TIMER (= -1 POSIX) signal_value (=1) :
SIGEV_SIGNAL_CODE_INIT( &event, SIGALRM, signal_value, signal_code );
timer_create(CLOCK_REALTIME, &event, &timer_id);
// :
itime.it_value.tv_sec = 4;
//4
itime.it_value.tv_nsec = 0;
itime.it_interval.tv_sec = 4; //4
itime.it_interval.tv_nsec = 0;
timer_settime(timer_id, 0, &itime, NULL);
printf("snsrs: interval timer launched\n");
// - :
for(i=0; i<5; i++) pthread_create(&tid[i], &attr, &sensor,
(void *) &seed[i]);
for(i=0; i<5; i++) pthread_join(tid[i], NULL);

ChannelCreate()
ChannelDestroy()
ConnectAttach()
ConnectDetach()
MsgSend()
MsgReceive()
MsgInfo()
MsgReply()

MsgWrite()
MsgRead()
MsgSendPulse ()
MsgReceivePulse()
MsgDeliverEvent()

3.6. ( API
QNX Neutrino). -,
, -

100

MsgError()

,
QNX Neutrino



(. - MsgSend*())
(.
- MsgReceive*())
,
struct _msg_info
(. - MsgReplyv())


(. MsgWritev())
(. MsgReadv())


. - , / . 6 -. , , . , , (. 1).

101

//message_ring_first.c
- PARENT
#include <stdlib.h>
#include <sys/netmgr.h>
/* ND_LOCAL_NODE=0 QNET,
*/
#include <process.h>
#include <sys/neutrino.h>

//system("clear"); //
par_id = getpid();
printf("PARENT with pid %d started. ", par_id);
chid = ChannelCreate(0); //
// , :
itoa(nd, nd_s, 10);
// QNET,
itoa(par_id, pid_s, 10); // pid

102

//--------------------------------------------------------------------------------------------------------------------main()
{
int chid;
int rcvid;
int coid;
int nd = ND_LOCAL_NODE;
// 0
pid_t par_id, chil_id;
char my_msg[7] = "PREVED";
char rmsg[20]="";
char nd_s[8 * sizeof( int ) + 1], pid_s[8 * sizeof( int ) + 1],
chid_s[8 * sizeof( int ) + 1],count_s[8 * sizeof( int ) + 1];
int status = 0;
char reply[15] = "Hi, Son!";
pid_t child_id;
int count=0;
int i;
struct _msg_info info;

}
//===============================================================================

103

itoa(chid, chid_s, 10);


//
itoa(count, count_s, 10); // -
printf("PARENT's nd = %d chid = %d\n", nd, chid);
chil_id = spawnl(P_NOWAIT, "message_ring-other.out", // "message_ring-other.out",
//
pid_s, chid_s, pid_s, chid_s, count_s, NULL );
delay(100);
//
//
for(i=0; i<2; i++) /* i = 0 , i = 1 -
(descendant) */
{
rcvid = MsgReceive(chid, rmsg, sizeof(rmsg), &info);//
printf("%d: received message from son %d is \"%s\"\n", par_id,
info.pid, rmsg);
if(i==1) strcpy(reply, "Bye, Son!");// -
MsgReply( rcvid, status, reply, 15 );//
if(i==1) //
{
printf("PARENT: The ring is enclosed. Terminating...\n");
ChannelDestroy(chid);
exit(0);
}
}

// message_ring_other.c // - ( message_ring-other.out)
#include <sys/neutrino.h>
#include <sys/netmgr.h>
#include <process.h>

//argv[1] // pid
//argv[2] /* .

104

//--------------------------------------------------------------------------------------------------------------------int main(int argc, const char *argv[])


// nd, chid
{
int nd = ND_LOCAL_NODE;
// 0;
pid_t other_pid;
pid_t ppid;
int chid;
int coid;
int rcvid;
int status = 0;
char son_msg[] = "PREVED, PARENT!";
char rmsg[20]="";
char par_pid_s[8 * sizeof(int) + 1], chid_s[8 * sizeof(int) + 1],
count_s[8 * sizeof(int) + 1];
pid_t child_id;
char reply[15] = "Hi, Son!";
int count = 0;
struct _msg_info info;

*/
ppid = atoi(argv[3]);
// pid
chid = atoi(argv[4]);
//
other_pid = getpid();
// pid
count = atoi(argv[5]);
//

105

printf("\n\tDESCENDANT #%d with pid %d started.


Parent's nd=%d ppid=%d chid=%d\n", count, other_pid, nd, ppid, chid);
//
++count;
if(count<6)
//
{
coid = ConnectAttach(nd, ppid, chid, _NTO_SIDE_CHANNEL, 0);/*
*/
MsgSend( coid, son_msg, sizeof(son_msg), rmsg, 20 );
printf("\t%d: The reply from parent is \"%s\"\n", other_pid, rmsg);
ConnectDetach(coid); //
sleep(1);
}
else
// ,
{
coid = ConnectAttach(nd, atoi(argv[1]), atoi(argv[2]),
_NTO_SIDE_CHANNEL, 0);
MsgSend( coid, son_msg, sizeof(son_msg), rmsg, 20 );
printf("\t%d: The last reply from PARENT is \"%s\"\n", other_pid,

//
chid = ChannelCreate(0);
itoa(other_pid, par_pid_s, 10);
itoa(chid, chid_s, 10);
itoa(count, count_s, 10);
child_id = spawnl(P_NOWAIT, "message_ring-other.out",
"message_ring-other.out",
argv[1], argv[2], par_pid_s, chid_s, count_s, NULL);
delay(100);
rcvid = MsgReceive(chid, rmsg, sizeof(rmsg), &info);
printf("%d: received message from parent %d is \"%s\"\n", other_pid,
info.pid, rmsg);
MsgReply( rcvid, status, reply, 15 );
ChannelDestroy(chid);

106

rmsg);
ConnectDetach(coid);
exit(0);
//

107

QNX Neutrino. RSA_Server ()


RSA, -.
- RSA_Client () 5 QNXNeutrino . -
RSA_Receiver () . RSA-Receiver

.
, ,
RSA ( ):
- p q. ( RSA_Server p q
isprime()).
- e, (p-1)*(q-1). e , ..
(p-1)*(q-1) .
- d, (e*d) % (p-1)(q-1) = =1. ( e d RSA_Server uclid(), ).
- (, p*q) () (
encryption-), (d, p*q) () (d - decryption-). C , T, C = (T^e)%(p*q), T = (C^e)%(p*q)
( ^ , % - .
(x^y)%n x_pow_y_mod_z1(),
cl_ser5.h).

//------------------------------------------------------------------------------------------------------uint64_t x_pow_y_mod_z1(uint64_t x, uint64_t y, uint64_t n)


{
// (x^y)%n RSA
uint64_t s=1, t=x, u=y, i;
while(u) {

108

- (.. ) RSA-
p q p*q, p*q (1024 2048-).
.
RSA_Server5, RSA_Client5 RSA_Receiver5.
// cl_ser5.h
#include <inttypes.h>
#include <sys/neutrino.h>
#include <math.h>
#include <sys/dispatch.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#define ATTACH_POINT "RSA-Server" // ,
( /dev/name/local/)
typedef struct _my_data { //
//struct _pulse hdr;
struct sigevent evnt;
uint64_t data;
} my_data_t;

if(u&1) s = (s*t)%n;
u >>=1;
t = (t*t)%n;

}
return s;

}
================================================================================
// RSA_Server5.c
//# gcc -oRSA_Server5.out RSA_Server5.c -Ldir /lib/libm.a
//# qcc -oRSA_Server5.out RSA_Server5.c -l /lib/libm.a

#define BUFF_SIZE (256 + 1)


//---------------------------------------------------------------------------------uint64_t euclid( uint64_t m, uint64_t n, int64_t* uu, int64_t* vv)
{ // . (laws.pdf)
int64_t u[3]={1,0,m}, v[3]={0,1,n}, t[3], q;
int i;
while(v[2] != 0) {
q = u[2]/v[2];
for(i=0; i<3; i++) {
t[i]=u[i]-v[i]*q;
u[i]=v[i];
v[i]=t[i];
}

109

#include "cl_ser5.h"

//printf("*q=%lld u[0]=%lld u[1]=%lld u[2]=%lld v[0]=%lld


v[1]=%lld v[2]=%lld\n", q,u[0],u[1],u[2],v[0],v[1],v[2]);

}
*uu = u[0]; *vv = u[1];
//printf("***%lld %lld %lld %lld
v[0], v[1], v[2]);
return u[2];
// gcd

%lld

%lld\n", u[0], u[1], u[2],

110

}
//---------------------------------------------------------------------------------uint64_t isprime(uint64_t s)
{//
uint64_t m, n, i = 1;
long long u, v;
for(n=2ULL; n <= (uint64_t) ceil(sqrt((double)s)); n++)
if(euclid(s, n, &u, &v) > 1) {i=0; break;}
if(i) return s; else return i;
}
//---------------------------------------------------------------------------------main()
{
name_attach_t *attach;
int rcvid;
uint64_t sqrt_ullmax, i, p=0ULL, q=0ULL, e, aux, gcd, plain_text,
cipher;
int64_t u, v, d;
int k1, k2, j;

int scale = 80003;


char buf[50], buff[BUFF_SIZE], pq[100]; // buf -for long p*q numbers
uint64_t* ptr;
struct sigevent r_event; /* ,
MsgDeliverEvent */
my_data_t msg;
int cycle_brk = 0;
int receiver_rcvid;
setbuf(stdout, NULL);
if( confstr( _CS_RELEASE, buff, BUFF_SIZE ) > 0 ) // QNX
printf( "SERVER: QNX Release: %s. Generating keys...\n", buff );

j = 0; //
for(i = sqrt_ullmax/scale; i<sqrt_ullmax/scale+scale; i++) {
if(isprime(i))
{
if(j==k1) p=i;
if(j==k2) {q=i; break;}
j++;
}
}

111

/*------------------------- RSA----------------------------*/
srand((int) (time(NULL)*rand()));
k1 = rand() / 1000;
// k1 k2
do k2=rand() / 1000; while(k2 <= k1);
sqrt_ullmax = (uint64_t) sqrt((double)ULLONG_MAX);

/* Create a local name (/dev/name/local/...) */


if ((attach = name_attach(NULL, ATTACH_POINT, 0)) == NULL) {
return EXIT_FAILURE;
} /*
*/

112

//printf("p=%lld
q=%lld\n", p, q);
aux = (p-1)*(q-1);
do e = rand() / 8000; while (e<=3); // RAND_MAX=32767u (. stdlib.h)
e = (e % 2) ? e : e - 1;
//printf("e0=%lld ", e);
for(e; e < aux; e += 2)
if((gcd = euclid(e, aux, &u, &v)) == 1ULL) break; // 2 =< e <= (p-1)(q-1)
d = u;
//printf("e=%lld d=u=%lld v=%lld test: e*u+aux*v=%lld (must be 1)\n",
e, u, v, e*u+aux*v);
if(u < 0)
{
d += aux;
/*printf("d=%lld e*d %% test: aux=%lld (must be 1)\n",
d, e*d % aux); */
}
printf("Private key: (e=%lld p*q=%lld).\n
Public key: (d=%lld p*q=%lld).\n", e, p*q, d, p*q);
/*------------------------- RSA-------------------------*/

113

ptr = calloc(7, sizeof(uint64_t)); /* 5


( d, p*q) */
while (1)
{
rcvid = MsgReceive(attach->chid, &msg, sizeof(msg), NULL); /*
*/
if (rcvid == -1) break; // MsgReceive()
else if (msg.evnt.sigev_code == _PULSE_CODE_MINAVAIL) /*
RSA_Client */
{
plain_text = msg.data;
//
printf("SERVER: received message %u\n", plain_text);
/*-------------------------------------------*/
// = (^e) mod (p*q)
printf("\tENCRYPTION : (%lld^%lld)%%%lld ",
plain_text, e, p*q);
cipher = x_pow_y_mod_z1(plain_text, e, p*q);//
printf("cipher=%lld\n", cipher);
*ptr++ = cipher; //
MsgError(rcvid, 0);// RSA_Client
if(++cycle_brk >= 7) break;// ,
}
else if(msg.evnt.sigev_code == _PULSE_CODE_MINAVAIL+1) /*
RSA_Receiver */
{

}
*ptr = d;
//
*++ptr = p*q;
ptr -= 6;
for(j=0; j < 7; j++) {printf("%lld ", *ptr); if(j==6) break; ptr++; }
ptr -= 6;
printf("\n");
MsgDeliverEvent(receiver_rcvid, &r_event); /* RSA_Receiver ,
, */

114

printf("received message with pulse code


_PULSE_CODE_MINAVAIL+1\n");
receiver_rcvid = rcvid;
// RSA_Receiver
r_event = msg.evnt;
/* ,
RSA_Receiver */
MsgError(receiver_rcvid, 0); /*
RSA_ Receiver */
if(++cycle_brk >= 7) break; /* ,
*/
}
else { // ,
printf("received other's message \n");
MsgError(rcvid, 0);
if(++cycle_brk >= 7) break; /* ,
*/
}

do {// RSA_Receiver
rcvid = MsgReceive(attach->chid, &msg, sizeof(msg), NULL);
} while(msg.evnt.sigev_code != _PULSE_CODE_MINAVAIL+2);
MsgWrite(rcvid, ptr, 7*sizeof(uint64_t), 0);// RSA_Receiver
MsgReply(rcvid, 0, NULL, 0); // RSA_ Receiver
free(ptr);
name_detach(attach, 0);

main()
{
my_data_t msg;
uint64_t reply=12345;
int fd, i;
if ((fd = name_open(ATTACH_POINT, 0)) == -1) { //
return EXIT_FAILURE;
//
}
msg.evnt.sigev_notify = SIGEV_PULSE; /*
, , RSA_Client5 */

115

}
// RSA_Client5.c
//#gcc -oRSA_Client5.out RSA_Client5.c -Ldir /lib/libm.a
//#qcc -oRSA_Client5.out RSA_Client5.c -l /lib/libm.a
#include "cl_ser5.h"

msg.evnt.sigev_coid = fd;
//msg.evnt.sigev_priority =
msg.evnt.sigev_code = _PULSE_CODE_MINAVAIL;
//msg.evnt.sigev_value =
for (i = 0; i < 5; i++) //
{
//5
msg.data = rand() / 873;
printf("CLIENT : sending %u \n", msg.data);
if (
MsgSend(fd, &msg, sizeof(msg), NULL, 0) == -1) break;
//printf("\t Received Reply from Server %u\n", reply);

}
// RSA_Receiver5.c
//qcc -oRSA_Receiver5.out RSA_Receiver5.c -l /lib/libm.a /*
*/
// ,
#include "cl_ser5.h"
#define MY_PULSE_CODE _PULSE_CODE_MINAVAIL+5
#define MY_PULSE_VALUE 97531
//-------------------------------------------------------------------------------------------------------------------------------------main()
{
int fd;

116

}
name_close(fd);

struct _pulse my_pulse;


my_data_t msg;
int i;
int chid, coid;
uint64_t buf[7]; // 5 , (d, p*q)-
int64_t d;
uint64_t plain_text, pq;
/* , RSA_Server5 ,
*/
coid = ConnectAttach( 0, 0, chid, _NTO_SIDE_CHANNEL, 0 );/*
*/
if ((fd = name_open(ATTACH_POINT, 0)) == -1) {//
return EXIT_FAILURE;
//
}
msg.evnt.sigev_notify = SIGEV_PULSE; /*
, , RSA_Receiver5
*/
msg.evnt.sigev_coid = coid;
//msg.evnt.sigev_priority =
msg.evnt.sigev_code = _PULSE_CODE_MINAVAIL+1;
msg.evnt.sigev_value.sival_int = MY_PULSE_VALUE;
MsgSend( fd, &msg, sizeof(msg), NULL, 0 ); // send event to server
//printf("*** _PULSE_CODE_MINAVAIL+1=%d\n", _PULSE_CODE_MINAVAIL+1);
chid = ChannelCreate(0);

117

do
{

MsgReceivePulse(chid, &my_pulse, sizeof(struct _pulse), NULL);


/* , .
MsgDeliverEvent() */
printf("* received pulse event from server with code %d\n",
my_pulse.code);
} while (my_pulse.code !=_PULSE_CODE_MINAVAIL+1);
printf("*** received pulse event from server with code %d and value
%d\n", my_pulse.code, my_pulse.value.sival_int);
118

msg.evnt.sigev_code = _PULSE_CODE_MINAVAIL+2;
MsgSend(fd, &msg, sizeof(msg), buf, sizeof(buf));
/*
, 5 - buf */
for(i=0; i < 7; i++) printf("%lld ", buf[i]);/*
*/
printf("\n");
d = buf[5];
pq = buf[6];
/*------------------------------------------*/
// = (^d) mod pq
for(i=0; i < 5; i++)
{
plain_text = x_pow_y_mod_z1(buf[i], d, pq);
printf("plain_text=%lld\n", plain_text);
}

name_close(fd);
// , name_open()
ConnectDetach(coid); //
ChannelDestroy(chid); //

#define BUFF_SIZE (256 + 1)


// ULONGLONG_MAX = 4294967295 sqrt(ULONGLONG_MAX) = 65535 USHRT_MAX 65535
//------------------------------------------------------------------------------------------------------char* x_pow_y_mod_z3(uint64_t x, uint64_t y, char z[])
//
t
e
p*q
{ // (t^e)%(p*q) QNX 6.3.*
char *s_rezult[100];
FILE* f;

119

}
( ). C 64 , RSA .
, , GNU GMP
(http://www.swox.com/gmp/). UNIX- - bc
. bc RSA- / bc (pipes) UNIX.
#include <stdio.h>
#include <limits.h>
#include <inttypes.h>
#include <stdlib.h>
#include <unistd.h>

char sh_command[]="bc < a_pow_b_mod_n-bc";/*


bc */
// : "bc a_pow_b_mod_n-bc";
char bc_commands[]= // bc
"s=\nwhile(y!=0){\n\tif(y%2) s=(s*x)%n\n\ty /= 2\n\tx=(x*x)%n\n}\ns\n";
remove("a_pow_b_mod_n-bc");// "a_pow_b_mod_n-bc"- bc
ff = fopen("a_pow_b_mod_n-bc", "a");//
fprintf(ff, "x=%lld\ny=%lld\nn=%s\n", x, y, z);
fprintf(ff, "%s", bc_commands);
fclose(ff);

}
//------------------------------------------------------------------------------------------------------main()
{
uint64_t t, e=17ULL, p=3480837ULL, q=3482211ULL;
char buff[BUFF_SIZE], sh_command[100], bc_command[100],
gzip_command[100], pq[100], cipher[100];
FILE *pipe_fp, *pipe_fp2;

120

f = popen(sh_command, "r");// bc
fgets(s_rezult[0], 100, f);//
//puts(s_rezult);
return *s_rezult;

printf( "ULONG_MAX=%u, ULLONG_MAX=%u, ULONGLONG_MAX=%u\n",ULONG_MAX,


ULLONG_MAX, ULONGLONG_MAX);/*
( limits.h) */
printf("x=3480837*3482211=%lld(%%lld)\n", 348083*348221);
printf("x=3480837*3482211=%u(%%u)\n", 348083*348221); /*
, */
confstr( _CS_RELEASE, buff, BUFF_SIZE ); // (release) QNX
printf( "QNX Release: %s\n", buff );

/* QNX 6.2.
"proba.gz" */

remove("proba.gz");
for( t=175ULL; t < 186; t++)
{
sprintf(bc_command, "(%lld^%lld)%%%lld", t, e, p*q);
printf("%s = ", bc_command);
sprintf(sh_command, "echo \"%s\" | bc", bc_command);
pipe_fp = popen(sh_command, "r");
fgets(cipher, 100, pipe_fp);
pclose(pipe_fp);
printf("%s", cipher);
sprintf(gzip_command, "echo \"%s\" | gzip -fc >> proba.gz",

121

if( ! memcmp( "6.2.", buff, 4))

}
else if( ! memcmp( "6.3.", buff, 4)) // QNX 6.3.
{
sprintf(pq, "%lld", p*q);
for( t=175ULL; t < 186; t++)
{
printf("(%u", t);
printf("^%u)", e);
printf("%%%s=", pq);
strcpy(cipher, x_pow_y_mod_z3(t, e, pq));
printf("%s", cipher);
}
}

/* :
# ./big_pow_with_bc6.out
ULONG_MAX=4294967295, ULLONG_MAX=4294967295, ULONGLONG_MAX=4294967295
x=3480837*3482211=577719951765990823(%lld)
x=3480837*3482211=950726055(%u)
QNX Release: 6.3.0
(175^17)%12121008890607=11222799716509

122

cipher); // #gzip -df proba.gz


pipe_fp2 = popen(gzip_command, "w");
pclose(pipe_fp2);

(176^17)%12121008890607=11998102008764
(177^17)%12121008890607=6101387353053
(178^17)%12121008890607=8988491121169
(179^17)%12121008890607=2723319392012
(180^17)%12121008890607=7105026443589
(181^17)%12121008890607=3909385636786
(182^17)%12121008890607=4902636545753
(183^17)%12121008890607=7174218074796
(184^17)%12121008890607=10072806839179
(185^17)%12121008890607=4517402993057
#
123

# ./big_pow_with_bc6.out
ULONG_MAX=4294967295, ULLONG_MAX=4294967295, ULONGLONG_MAX=4294967295
x=3480837*3482211=-3344241241(%lld)
x=3480837*3482211=950726055(%u)
QNX Release: 6.2.0
(175^17)%12121008890607 = 11222799716509
(176^17)%12121008890607 = 11998102008764
(177^17)%12121008890607 = 6101387353053
(178^17)%12121008890607 = 8988491121169
(179^17)%12121008890607 = 2723319392012
(180^17)%12121008890607 = 7105026443589
(181^17)%12121008890607 = 3909385636786
(182^17)%12121008890607 = 4482252218624
(183^17)%12121008890607 = 7174218074796

#bc
(992802946^2)%1234749221
127094068
(992802946^3)%1234749221
210000111
(992802946^4)%1234749221
1414285714285714286193147029 ???
(992802946^5)%1234749221
915194871
(992802946^6)%1234749221
270614289
(992802946^7)%1234749221
459978554

124

(184^17)%12121008890607 = 10072806839179
(185^17)%12121008890607 = 4517402993057
# */
. - bc QNX Momentics :
QNX (6.2 6.3)
, . , QNX 6.2 . QNX 6.3 (. ). . .
bc 6.3 6.2.
. , , ( ):

(992802946^8)%1234749221
501686632
:
# bc
(65534^101)%2345678
1113772 -

(65540^101)%2345678
3000000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000030000000000000000000000000000000\
0000000000000000000000000000000293672 = 293672
, 2008 . 6.3.0
SP3+QNX Neutrino Core OS 6.3.2A

125

(65535^101)%2345678
3000000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000002197645
= 2197645

QNX, bc !

126

5. 4
( )
. .5.1
C QNX Neutrino


timespec
,
timer_create()
TimerCreate()
()
timer_settime()
TimerSettime()

timer_gettime()
TimerInfo()
,
timer_delete()
TimerDestroy()

,
ualarm()
SIGALRM
, SIGALRM
alarm()
TimerAlarm()

timer_timeout()
TimerTimeout()

clock_getres()
( )
ClockPeriod()
( )
clock_gettime()

ClockTime()
clock_settime()

ClockCycles()
64-

4.1.
. main , . ,
. ,
main, , .
.
TSC . . time
( #time ./_) .

127

SYSPAGE_ENTRY()
, timespec
timespec2nsec()

timespec
nsec2timespec()
(
sleep()
)
delay()

usleep()

,
nanosleep()
timespec
,
clock_nanosleep()
timespec

#include
#include
#include
#include
#include
#include

<stdlib.h>
<pthread.h>
<sys/neutrino.h>
<errno.h>
<inttypes.h>
<sys/syspage.h>

#define MY_PULSE_CODE _PULSE_CODE_MINAVAIL+3


#define BILLION 1000000000L; // 1
int chid; //

clock_gettime( CLOCK_REALTIME, &start_time); /*


*/
printf("\tChild: this is thread %d\n", pthread_self());

128

//--------------------------------------------------------------------------------------------------------------------------------void * function( void* arg )// ,


{
struct sigevent event;
struct timespec timeout;
int ret;
struct _pulse pulse;
struct timespec start_time, stop_time;
double accum, timeout_in_sec;
uint64_t tick_time;
struct _clockperiod tick;

event.sigev_notify = SIGEV_UNBLOCK; /* ,
MsgReceivePulse_r */
timeout.tv_sec = 2; // pthread_join() 2.0
timeout.tv_nsec = 0;
timeout_in_sec =(double)timeout.tv_sec + double)timeout.tv_nsec/BILLION;
//
do //
{
timer_timeout(CLOCK_REALTIME, _NTO_TIMEOUT_RECEIVE, &event,
&timeout, NULL);
ret = MsgReceivePulse_r( chid, &pulse, sizeof(pulse), NULL );
129

if(ret == -ETIMEDOUT) //
{
printf("\tChild: ret=%d timeout %.3f s on pulse waiting
elapsed\n", ret, timeout_in_sec);
}
else
// , main
{
printf("\tChild: ret=%d, received termination pulse with code %d
and value %d\n", ret, pulse.code, pulse.value.sival_int);
clock_gettime( CLOCK_REALTIME, &stop_time); /*
*/
printf("\tChild thread stopped at %u sec %ld nsec system
time\n",(uint64_t)stop_time.tv_sec, stop_time.tv_nsec);

tick_time=(uint64_t(stop_time.tv_secstart_time.tv_sec)*BILLION+
(stop_time.tv_nsec - start_time.tv_nsec);/*
*/
accum = (double) tick_time / (double)BILLION; );/*
*/
ClockPeriod(CLOCK_REALTIME, NULL, &tick, 0); /*
*/
printf( "\tChild: System clock tick is %ld ns.
Child time is %lf s %lf tick.\n", tick.nsec, accum,
(double)tick_time / (double)tick.nsec);
pthread_exit(NULL);

}
//-------------------------------------------------------------------------------------------------------------------------int main( void )
{
pthread_attr_t attr;
pthread_t thr;
struct sigevent event, timer_event;
struct itimerspec itime;
struct timespec timeout;
double wait_time = 0.0, timeout_in_sec;
int ret;
timer_t timer_id;
uint64_t cps, cycle1, cycle2, ncycles;

130

}
} while (1);

timer_create(CLOCK_REALTIME, &timer_event, &timer_id);//


itime.it_value.tv_sec = 7; // 7.0 .
itime.it_value.tv_nsec = 0;
itime.it_interval.tv_sec = 0;
itime.it_interval.tv_nsec = 0;
timer_settime(timer_id, 0, &itime, NULL); //
pthread_attr_init( &attr );

131

float sec;
cycle1=ClockCycles( ); // TSC main
printf("Main with pid %d starts\n", getpid());
event.sigev_notify = SIGEV_UNBLOCK; /* ,
pthread_join()*/
timeout.tv_sec = 1; // pthread_join() 1.05
timeout.tv_nsec = 50000000;
// 0.05
timeout_in_sec = (double)timeout.tv_sec+(double)timeout.tv_nsec/BILLION;
//
chid = ChannelCreate(0);
//
timer_event.sigev_notify = SIGEV_PULSE;// , -
timer_event.sigev_coid = ConnectAttach(0, 0, chid, _NTO_SIDE_CHANNEL,0);
timer_event.sigev_priority = getprio(0);/*
*/
timer_event.sigev_code = MY_PULSE_CODE; //
timer_event.sigev_value.sival_int = 12345;// ,

132

pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&thr, &attr, &function, NULL );//
for(;;)//
{
timer_timeout( CLOCK_REALTIME, _NTO_TIMEOUT_JOIN, &event, &timeout,
NULL);
ret = pthread_join(thr, NULL);
if(ret == ETIMEDOUT) //
{
wait_time += (double) timespec2nsec(&timeout) / BILLION;
printf("Main: ret=%d. Join_timeout %.3f s elapsed.
Waiting for child thread termination %.3f s\n",
ret, timeout_in_sec, wait_time );
}
else
// pthread_join() .
{
printf("Main: ret=%d. Child thread terminated\n", ret);
break;
}
}
ChannelDestroy(chid);
timer_delete(timer_id);
cycle2=ClockCycles( ); // TSC main
ncycles=cycle2-cycle1;
cps = SYSPAGE_ENTRY(qtime)->cycles_per_sec;
sec=(float)ncycles/cps;

printf("Main time is %f s\n", sec);// main TSC


return EXIT_SUCCESS;

133

134


1. , . QNX Neutrino 2: QNX Realtime
Platform - .: , 2001 - 480 .
- .:-, 2005 . -400 .
2. , .. QNX:
. 2- ., . . .: , 2004. 192 .
3. , .. QNX Momentics: . .:,2005.-256 .
http://swd.ru/index.php3?pid=499
4. , .. POSIX. 1
2. : : , 351400 /
.. . .: - . . 2005.-384 .
http://www.intuit.ru/department/se/pposix/
http://www.intuit.ru/department/se/posix2/
5. . . UNIX: = UNIX Network
Programming Volume 2: . ./ . . , W. R.
Stevens. -.: , 2003. -576 .: . -(-).
6. ., . QNX/UNIX: /
., . .: -, 2006. -288 .
- :
- qnx.org.ru.
- openqnx.com.
- qnxclub.net.

Você também pode gostar