Inter-Process Communication in Computer Architecture

 
C
o
m
p
u
t
e
r
 
A
r
c
h
i
t
e
c
t
u
r
e
 
a
n
d
 
O
p
e
r
a
t
i
n
g
 
S
y
s
t
e
m
s
L
e
c
t
u
r
e
 
9
:
 
I
n
t
e
r
-
P
r
o
c
e
s
s
 
C
o
m
m
u
n
i
c
a
t
i
o
n
 
Andrei Tatarnikov
 
a
t
a
t
a
r
n
i
k
o
v
@
h
s
e
.
r
u
@
a
n
d
r
e
w
t
0
3
0
1
 
Files
Pipes
Signals
Message Queues
Shared Memory
 
2
 
I
n
t
e
r
-
P
r
o
c
e
s
s
 
C
o
m
m
u
n
i
c
a
t
i
o
n
 
Asynchronous
One-byte
Delivered by OS (
kill
 system call and utility)
Can be caught by OS or the process itself
Examples: Ctrl-C = 
SIGINT
, Ctrl-\ = 
SIGQUIT
, Ctrl-Z =
SIGTSTP
 
3
 
S
i
g
n
a
l
s
 
4
 
N
e
v
e
r
 
E
n
d
i
n
g
 
P
r
o
g
r
a
m
 
#
i
n
c
l
u
d
e
 
<
s
t
d
i
o
.
h
>
#
i
n
c
l
u
d
e
 
<
u
n
i
s
t
d
.
h
>
i
n
t
 
m
a
i
n
(
i
n
t
 
a
r
g
c
,
 
c
h
a
r
 
*
a
r
g
v
[
]
)
 
{
 
 
 
 
 
 
 
 
i
n
t
 
i
;
 
 
 
 
 
 
 
 
f
o
r
(
i
=
0
;
;
 
i
+
+
)
 
{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
s
l
e
e
p
(
1
)
;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
p
r
i
n
t
f
(
"
%
d
\
n
"
,
 
i
)
;
 
 
 
 
 
 
 
 
}
 
 
 
 
 
 
 
 
r
e
t
u
r
n
 
0
;
}
 
Example program to be managed by signals:
 
kill
 utility — send a signal to a process
kill -l
 (slightly) platform-depended
kill -SIGNAL
example: suspend (
STOP
) / continue (
CONT
)
kill never-ending program with just 
kill
, kill -
HUP
, 9, 
SEGV
 :), 
STOP,
 and 
CONT
Types of processes (just a convention, both types runs by 
fork
()/
exec
())
interactive process: 
1 at each terminal can input and output to the terminal
background process (runs from shell with '
&
'): any number can only output to the
terminal
Changing type:
^Z 
to stop, 
fg
 to continue, 
bg
 to continue in background (complex)
When background process inputs from tty, in immediately 
STOP
ped, we can 
fg
 it
 
5
 
K
i
l
l
 
Send a signal: see 
kill
 system call at 
https://www.man7.org/
 
6
 
S
e
n
d
i
n
g
 
S
i
g
n
a
l
s
:
 
S
y
s
t
e
m
 
C
a
l
l
 
K
i
l
l
 
#include 
<stdio.h>
#include 
<sys/types.h>
#include 
<signal.h>
#include 
<stdlib.h>
int 
main(
int 
argc, 
char 
*argv[]) {
    
if 
(kill(atoi(argv[
1
]), atoi(argv[
2
])))
        perror(
"Can not kill"
);
    
return 
0
;
}
 
Try to kill foreign or non-existent process
 
7
 
H
a
n
d
l
i
n
g
 
S
i
g
n
a
l
s
 
#
i
n
c
l
u
d
e
 
<
s
t
d
i
o
.
h
>
#
i
n
c
l
u
d
e
 
<
u
n
i
s
t
d
.
h
>
#
i
n
c
l
u
d
e
 
<
s
i
g
n
a
l
.
h
>
v
o
i
d
 
h
a
n
d
l
e
r
(
i
n
t
 
s
i
g
)
 
{
 
 
 
 
p
r
i
n
t
f
(
"
C
a
u
g
h
t
 
%
d
\
n
"
,
 
s
i
g
)
;
}
i
n
t
 
m
a
i
n
(
i
n
t
 
a
r
g
c
,
 
c
h
a
r
 
*
a
r
g
v
[
]
)
 
{
 
 
 
 
s
i
g
n
a
l
(
S
I
G
I
N
T
,
 
h
a
n
d
l
e
r
)
;
 
 
 
 
s
i
g
n
a
l
(
S
I
G
S
E
G
V
,
 
h
a
n
d
l
e
r
)
;
 
 
 
 
i
n
t
 
i
;
 
 
 
 
f
o
r
(
i
=
0
;
;
 
i
+
+
)
 
{
 
 
 
 
 
 
s
l
e
e
p
(
1
)
;
 
 
 
 
 
 
p
r
i
n
t
f
(
"
%
d
\
n
"
,
 
i
)
;
 
 
 
 
}
 
 
 
 
r
e
t
u
r
n
 
0
;
}
 
Handler (
signal
):
needs to be registered
not all signals can be handled
(e. g. 
9
 and 
STOP
/
CONT
)
permission restrictions (by
process UID)
 
8
 
L
o
o
k
i
n
g
 
A
f
t
e
r
 
C
h
i
l
d
 
P
r
o
c
e
s
s
e
s
 
#
i
n
c
l
u
d
e
 
<
s
t
d
i
o
.
h
>
#
i
n
c
l
u
d
e
 
<
w
a
i
t
.
h
>
#
i
n
c
l
u
d
e
 
<
s
i
g
n
a
l
.
h
>
#
i
n
c
l
u
d
e
 
<
u
n
i
s
t
d
.
h
>
i
n
t
 
m
a
i
n
(
i
n
t
 
a
r
g
c
,
 
c
h
a
r
 
*
a
r
g
v
[
]
)
 
{
 
 
 
 
i
n
t
 
s
t
a
t
;
 
 
 
 
p
i
d
_
t
 
p
i
d
;
 
 
 
 
i
f
 
(
(
p
i
d
 
=
 
f
o
r
k
(
)
)
 
=
=
 
0
)
 
{
 
 
 
 
 
 
 
 
w
h
i
l
e
(
1
)
;
 
 
 
 
}
 
e
l
s
e
 
{
 
 
 
 
 
 
 
 
p
r
i
n
t
f
(
"
F
o
r
k
i
n
g
 
a
 
c
h
i
l
d
:
 
%
d
\
n
"
,
 
p
i
d
)
;
 
 
 
 
 
 
 
 
w
a
i
t
(
&
s
t
a
t
)
;
 
 
 
 
 
 
 
 
p
r
i
n
t
f
(
"
A
n
d
 
f
i
n
a
l
l
y
\
n
"
)
;
 
 
 
 
 
 
 
 
i
f
 
(
W
I
F
S
I
G
N
A
L
E
D
(
s
t
a
t
)
)
 
 
 
 
 
 
 
 
 
 
 
 
p
s
i
g
n
a
l
(
W
T
E
R
M
S
I
G
(
s
t
a
t
)
,
 
"
T
e
r
m
i
n
a
t
e
d
:
"
)
;
 
 
 
 
 
 
 
 
p
r
i
n
t
f
(
"
E
x
i
t
 
s
t
a
t
u
s
:
 
%
d
\
n
"
,
 
s
t
a
t
)
;
 
 
 
 
}
 
 
 
 
r
e
t
u
r
n
 
0
;
}
 
See wait for
WIFSIGNALED
/
WTERMSIG
 macros
 
See 
psignal
 
Base manpage: 
mq_overview 
at 
https://www.man7.org/
What we need for messaging:
Synchronous
Can store content
Can be queued
Can be prioritized
Every message is delivered over certain queue
 
9
 
M
e
s
s
a
g
e
 
Q
u
e
u
e
s
 
10
 
C
r
e
a
t
i
n
g
 
M
e
s
s
a
g
e
 
Q
u
e
u
e
 
#include 
<mqueue.h>
#include 
<sys/stat.h>
#include 
<fcntl.h>
#include 
<stdio.h>
int 
main(
int 
argc, 
char 
*argv[]) {
    mqd_t mqd;
    
struct 
mq_attr attr;
    attr.mq_maxmsg = 
10
;
    attr.mq_msgsize = 
2048
;
    mqd = mq_open(argv[
1
], O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR, attr);
    
return 
0
;
}
 
Queue is for 
10
 messages 
2048
 bytes each
Queue is creating for read/write, if there is no queue
with the same name, or else an error is generated
Omitting 
O_EXCL
 allows to re-create a queue with
the same name, purging all messages, whit is
probably not a good idea
 
11
 
S
e
n
d
i
n
g
 
M
e
s
s
a
g
e
s
 
#include 
<mqueue.h>
#include 
<fcntl.h>
#include 
<string.h>
#include 
<stdlib.h>
int 
main(
int 
argc, 
char 
*argv[]) {
    mqd_t mqd;
    
unsigned int 
prio;
    mqd = mq_open(argv[
1
], O_WRONLY);
    prio = atoi(argv[
2
]);
    mq_send(mqd, argv[
3
], strlen(argv[
3
]), prio);
    
return 
0
;
}
 
Priority varies from 0 (lowest) to system-
depended maximum (at least 
31
, 
32767
 in
Linux)
Message content is a byte array, it does not
have to be zero-terminating string
POSIX queue provides prioritization
mechanism. Earliest massage from higher
priority messages subset is to be delivered
first.
 
12
 
R
e
c
e
i
v
i
n
g
 
M
e
s
s
a
g
e
s
 
#
i
n
c
l
u
d
e
 
<
m
q
u
e
u
e
.
h
>
#
i
n
c
l
u
d
e
 
<
f
c
n
t
l
.
h
>
#
i
n
c
l
u
d
e
 
<
s
t
d
i
o
.
h
>
#
i
n
c
l
u
d
e
 
<
s
t
d
l
i
b
.
h
>
i
n
t
 
m
a
i
n
(
i
n
t
 
a
r
g
c
,
 
c
h
a
r
 
*
a
r
g
v
[
]
)
 
{
 
 
 
 
m
q
d
_
t
 
m
q
d
;
 
 
 
 
u
n
s
i
g
n
e
d
 
i
n
t
 
p
r
i
o
;
 
 
 
 
v
o
i
d
 
*
b
u
f
;
 
 
 
 
s
t
r
u
c
t
 
m
q
_
a
t
t
r
 
a
t
t
r
;
 
 
 
 
s
s
i
z
e
_
t
 
n
;
 
 
 
 
m
q
d
 
=
 
m
q
_
o
p
e
n
(
a
r
g
v
[
1
]
,
 
O
_
R
D
O
N
L
Y
)
;
 
 
 
 
m
q
_
g
e
t
a
t
t
r
(
m
q
d
,
 
&
a
t
t
r
)
;
 
 
 
 
b
u
f
 
=
 
m
a
l
l
o
c
(
a
t
t
r
.
m
q
_
m
s
g
s
i
z
e
)
;
 
 
 
 
n
 
=
 
m
q
_
r
e
c
e
i
v
e
(
m
q
d
,
 
b
u
f
,
 
a
t
t
r
.
m
q
_
m
s
g
s
i
z
e
,
 
&
p
r
i
o
)
;
 
 
 
 
p
r
i
n
t
f
(
"
R
e
a
d
 
%
l
d
 
b
y
t
e
s
;
 
p
r
i
o
r
i
t
y
 
=
 
%
u
\
n
"
,
 
(
l
o
n
g
)
 
n
,
 
p
r
i
o
)
;
 
 
 
 
f
r
e
e
(
b
u
f
)
;
 
 
 
 
r
e
t
u
r
n
 
0
;
}
 
Knowing nothing about message size, program
must retrieve this value from queue attributes
to provide an appropriate space in read buffer.
There's no mechanism of message typification,
so only size is printed
To remove a queue call 
mq_unlink(name
)
POSIX message API is implemented in 
librt
library, so compile program with -
lrt
 option.
 
Every 
mq_receive
 call returns a message if there's
one. If queue is empty
, mq_receive
() can wait for
message or return with fail status, depending on
O_NONBLOCK flag.
 
There's alternate method to notify program by signal:
a program calls 
mq_notify
 to subscribe on certain
queue. Every time message is arrived in queue, the
program gets a signal described in 
mq_notify
() and
can handle message asynchronously.
 
13
 
N
o
t
i
f
y
i
n
g
 
Kernel has a paging mechanism. When memory is limited, some memory
pages can be swapped out. When a program needs one of them:
TLB produces page miss (no physical memory is provided for the virtual address);
Kernel a loads corresponding page from disk and links to virtual memory page.
If paging out a .text section, there is no need to provide a space on swap,
because this data is already on disk — e. g. in the binary program file, from
which the process was started.
More general process of mapping file to memory is called memory map.
System call 
mmap
 asks kernel to map selected file to the virtual memory
address range. After this done, the range can be used as an ordinary array
filled with file's contents. The file has not to be read into memory completely,
Linux use paging mechanism to represent corresponded file parts.
 
14
 
M
e
m
o
r
y
 
M
a
p
p
i
n
g
 
15
 
M
e
m
o
r
y
 
M
a
p
p
i
n
g
 
:
 
S
y
s
t
e
m
 
C
a
l
l
s
#include 
<sys/mman.h>
#include 
<sys/stat.h>
#include 
<stdio.h>
#include 
<fcntl.h>
int 
main(
int 
argc, 
char 
*argv[]) {
    
char 
*addr;
    
int 
fd;
    
struct 
stat sb;
    fd = open(argv[
1
], O_RDONLY);
    fstat(fd, &sb);
    addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 
0
);
    fwrite(addr, 
1
, sb.st_size, stdout);
    
return 
0
;
}
 
PROT_READ
 means that memory-mapped pages can
only be read by the program
MAP_PRIVATE
 means the program observe some
fixed state of the file
write to memory-mapped area does not change the
file itself
program supposes file can not be changed while
memory-mapped in 
MAP_PRIVATE
 mode
fstat
 is used to determine file size (it discovers other
file properties as well)
E
x
a
m
p
l
e
 
o
f
 
s
i
m
p
l
e
 
c
a
t
 
a
n
a
l
o
g
,
 
t
h
a
t
 
m
e
m
o
r
y
-
m
a
p
s
 
f
i
l
e
 
a
n
d
 
t
h
a
n
 
j
u
s
t
 
w
r
i
t
e
s
 
i
t
 
t
o
 
s
t
d
o
u
t
:
 
See page 
shm_overview 
at 
https://man7.org
 
Multiple processes can have some of their virtual memory
pages translated to the same physical page. Then they can
communicate through this shared area called shared memory.
 
POSIX shared memory implemented over memory-mapped file
abstraction.
 
First we need to open named shared memory object (shared
memory analog of queue, shmobj for short). Programs can
memory-map this object, read and write to it.
 
16
 
S
h
a
r
e
d
 
M
e
m
o
r
y
 
17
 
S
h
a
r
e
d
 
M
e
m
o
r
y
 
:
 
C
r
e
a
t
e
#include 
<stdio.h>
#include 
<sys/stat.h>
#include 
<fcntl.h>
#include 
<unistd.h>
#include 
<sys/mman.h>
#include 
<stdlib.h>
int 
main(
int 
argc, 
char 
*argv[]) {
   
int 
fd;
   size_t size;
   
void 
*addr;
   fd = shm_open(argv[
1
], O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
   size = atol(argv[
2
]);
   ftruncate(fd, size);
   addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 
0
);
   close(fd);
   
return 
0
;
}
 
Modes and permissions of the object are the same as when
creating a queue.
There is no sense in having newly created shmobj size other than
zero, so 
ftruncate
() call.
We call 
mmap
() for declaring the object shared (with
MAP_SHARED
, of course).
O
pen named 
shared memory object
 (shared memory analog of queue, 
shmobj
 for short).
P
r
o
g
r
a
m
s
 
c
a
n
 
m
m
a
p
 
t
h
i
s
 
o
b
j
e
c
t
,
 
r
e
a
d
 
a
n
d
 
w
r
i
t
e
 
t
o
 
i
t
.
 
18
 
S
h
a
r
e
d
 
M
e
m
o
r
y
 
:
 
W
r
i
t
e
#
i
n
c
l
u
d
e
 
<
s
t
d
i
o
.
h
>
#
i
n
c
l
u
d
e
 
<
f
c
n
t
l
.
h
>
#
i
n
c
l
u
d
e
 
<
s
y
s
/
m
m
a
n
.
h
>
#
i
n
c
l
u
d
e
 
<
s
t
r
i
n
g
.
h
>
#
i
n
c
l
u
d
e
 
<
u
n
i
s
t
d
.
h
>
i
n
t
 
m
a
i
n
(
i
n
t
 
a
r
g
c
,
 
c
h
a
r
 
*
a
r
g
v
[
]
)
 
{
 
 
 
 
i
n
t
 
f
d
;
 
 
 
 
s
i
z
e
_
t
 
l
e
n
;
 
 
 
 
c
h
a
r
 
*
a
d
d
r
;
 
 
 
 
f
d
 
=
 
s
h
m
_
o
p
e
n
(
a
r
g
v
[
1
]
,
 
O
_
R
D
W
R
,
 
0
)
;
 
 
 
 
l
e
n
 
=
 
s
t
r
l
e
n
(
a
r
g
v
[
2
]
)
;
 
 
 
 
f
t
r
u
n
c
a
t
e
(
f
d
,
 
l
e
n
)
;
 
 
 
 
a
d
d
r
 
=
 
m
m
a
p
(
N
U
L
L
,
 
l
e
n
,
 
P
R
O
T
_
R
E
A
D
 
|
 
P
R
O
T
_
W
R
I
T
E
,
 
M
A
P
_
S
H
A
R
E
D
,
 
f
d
,
 
0
)
;
 
 
 
 
c
l
o
s
e
(
f
d
)
;
 
 
 
 
p
r
i
n
t
f
(
"
C
o
p
y
i
n
g
 
%
d
 
b
y
t
e
s
\
n
"
,
 
l
e
n
)
;
 
 
 
 
m
e
m
c
p
y
(
a
d
d
r
,
 
a
r
g
v
[
2
]
,
 
l
e
n
)
;
 
 
 
 
r
e
t
u
r
n
 
0
;
}
 
There is no difference if you open shmobj for
reading/writing or just writing, it is memory
 
The smobj descriptor only needed when opening
shmobj, we can close it just after 
mmap
()
 
To write to the shared memory, program opens shmobj,
mmaps it and uses the memory as ordinary array
 
19
 
S
h
a
r
e
d
 
M
e
m
o
r
y
 
:
 
R
e
a
d
 
#
i
n
c
l
u
d
e
 
<
s
t
d
i
o
.
h
>
#
i
n
c
l
u
d
e
 
<
f
c
n
t
l
.
h
>
#
i
n
c
l
u
d
e
 
<
s
y
s
/
m
m
a
n
.
h
>
#
i
n
c
l
u
d
e
 
<
s
y
s
/
s
t
a
t
.
h
>
#
i
n
c
l
u
d
e
 
<
u
n
i
s
t
d
.
h
>
i
n
t
 
m
a
i
n
(
i
n
t
 
a
r
g
c
,
 
c
h
a
r
 
*
a
r
g
v
[
]
)
 
{
 
 
 
 
i
n
t
 
f
d
;
 
 
 
 
c
h
a
r
 
*
a
d
d
r
;
 
 
 
 
s
t
r
u
c
t
 
s
t
a
t
 
s
b
;
 
 
 
 
f
d
 
=
 
s
h
m
_
o
p
e
n
(
a
r
g
v
[
1
]
,
 
O
_
R
D
O
N
L
Y
,
 
0
)
;
 
 
 
 
f
s
t
a
t
(
f
d
,
 
&
s
b
)
;
 
 
 
 
a
d
d
r
 
=
 
m
m
a
p
(
N
U
L
L
,
 
s
b
.
s
t
_
s
i
z
e
,
 
P
R
O
T
_
R
E
A
D
,
 
M
A
P
_
S
H
A
R
E
D
,
 
f
d
,
 
0
)
;
 
 
 
 
c
l
o
s
e
(
f
d
)
;
 
 
 
 
f
w
r
i
t
e
(
a
d
d
r
,
 
1
,
 
s
b
.
s
t
_
s
i
z
e
,
 
s
t
d
o
u
t
)
;
 
 
 
 
p
r
i
n
t
f
(
"
\
n
 
D
o
n
e
"
)
;
 
 
 
 
r
e
t
u
r
n
 
0
;
}
 
To read from shared memory, the program opens
shmobj and tread it like mmapped file:
 
Note 
fstat
 can be used to determine shared
memory size as well as to determine file size
 
As usual, to stop using shmobj, one shall
unlink it with 
shm_unlink
(name)
 
A
n
y
 
Q
u
e
s
t
i
o
n
s
?
 
20
Slide Note
Embed
Share

Explore the key concepts of Inter-Process Communication (IPC) in computer architecture, covering topics such as signals, message queues, shared memory, and handling signals. Learn how to send and handle signals, manage never-ending programs, and control processes using utilities like kill. Dive into the different types of processes, interactive vs. background, and understand how to change process types effectively.

  • Computer Architecture
  • Inter-Process Communication
  • Signals
  • IPC
  • Operating Systems

Uploaded on Sep 19, 2024 | 0 Views


Download Presentation

Please find below an Image/Link to download the presentation.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. Download presentation by click this link. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.

E N D

Presentation Transcript


  1. Computer Architecture Computer Architecture and Lecture 9: Inter Lecture 9: Inter- -Process Communication Process Communication and Operating Systems Operating Systems Andrei Tatarnikov atatarnikov@hse.ru atatarnikov@hse.ru @andrewt0301 @andrewt0301

  2. Inter Inter- -Process Communication Process Communication Files Pipes Signals Message Queues Shared Memory 2

  3. Signals Signals Asynchronous One-byte Delivered by OS (kill system call and utility) Can be caught by OS or the process itself Examples: Ctrl-C = SIGINT, Ctrl-\ = SIGQUIT, Ctrl-Z = SIGTSTP 3

  4. Never Ending Program Never Ending Program Example program to be managed by signals: #include <stdio.h> #include <unistd.h> int main(int argc, char *argv[]) { int i; for(i=0;; i++) { sleep(1); printf("%d\ \n n", i); } return 0; } 4

  5. Kill Kill kill utility send a signal to a process kill -l (slightly) platform-depended kill -SIGNAL example: suspend (STOP) / continue (CONT) kill never-ending program with just kill, kill -HUP, 9, SEGV :), STOP, and CONT Types of processes (just a convention, both types runs by fork()/exec()) interactive process: 1 at each terminal can input and output to the terminal background process (runs from shell with '&'): any number can only output to the terminal Changing type: ^Z to stop, fg to continue, bg to continue in background (complex) When background process inputs from tty, in immediately STOPped, we can fg it 5

  6. Sending Signals: System Call Kill Sending Signals: System Call Kill Send a signal: see kill system call at https://www.man7.org/ #include <stdio.h> #include <sys/types.h> #include <signal.h> #include <stdlib.h> int main(int argc, char *argv[]) { if (kill(atoi(argv[1]), atoi(argv[2]))) perror("Can not kill"); return 0; } Try to kill foreign or non-existent process 6

  7. Handling Signals Handling Signals #include <stdio.h> #include <unistd.h> #include <signal.h> Handler (signal): needs to be registered not all signals can be handled (e. g. 9 and STOP/CONT) permission restrictions (by process UID) void handler(int sig) { printf("Caught %d\ \n n", sig); } int main(int argc, char *argv[]) { signal(SIGINT, handler); signal(SIGSEGV, handler); int i; for(i=0;; i++) { sleep(1); printf("%d\ \n n", i); } return 0; } 7

  8. Looking After Child Processes Looking After Child Processes #include <stdio.h> #include <wait.h> #include <signal.h> #include <unistd.h> See wait for WIFSIGNALED/WTERMSIG macros int main(int argc, char *argv[]) { int stat; pid_t pid; if ((pid = fork()) == 0) { while(1); } else { printf("Forking a child: %d\ \n n", pid); wait(&stat); printf("And finally \ \n n"); if (WIFSIGNALED(stat)) psignal(WTERMSIG(stat), "Terminated:"); printf("Exit status: %d\ \n n", stat); } return 0; } See psignal 8

  9. Message Queues Message Queues Base manpage: mq_overview at https://www.man7.org/ What we need for messaging: Synchronous Can store content Can be queued Can be prioritized Every message is delivered over certain queue 9

  10. Creating Message Queue Creating Message Queue #include <mqueue.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> Queue is for 10 messages 2048 bytes each Queue is creating for read/write, if there is no queue with the same name, or else an error is generated int main(int argc, char *argv[]) { mqd_t mqd; struct mq_attr attr; Omitting O_EXCL allows to re-create a queue with the same name, purging all messages, whit is probably not a good idea attr.mq_maxmsg = 10; attr.mq_msgsize = 2048; mqd = mq_open(argv[1], O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR, attr); return 0; } 10

  11. Sending Messages Sending Messages Priority varies from 0 (lowest) to system- depended maximum (at least 31, 32767 in Linux) Message content is a byte array, it does not have to be zero-terminating string POSIX queue provides prioritization mechanism. Earliest massage from higher priority messages subset is to be delivered first. #include <mqueue.h> #include <fcntl.h> #include <string.h> #include <stdlib.h> int main(int argc, char *argv[]) { mqd_t mqd; unsigned int prio; mqd = mq_open(argv[1], O_WRONLY); prio = atoi(argv[2]); mq_send(mqd, argv[3], strlen(argv[3]), prio); return 0; } 11

  12. Receiving Messages Receiving Messages #include <mqueue.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> Knowing nothing about message size, program must retrieve this value from queue attributes to provide an appropriate space in read buffer. There's no mechanism of message typification, so only size is printed To remove a queue call mq_unlink(name) POSIX message API is implemented in librt library, so compile program with -lrt option. int main(int argc, char *argv[]) { mqd_t mqd; unsigned int prio; void *buf; struct mq_attr attr; ssize_t n; mqd = mq_open(argv[1], O_RDONLY); mq_getattr(mqd, &attr); buf = malloc(attr.mq_msgsize); n = mq_receive(mqd, buf, attr.mq_msgsize, &prio); printf("Read %ld bytes; priority = %u\ \n n", (long) n, prio); free(buf); return 0; 12 }

  13. Notifying Notifying Every mq_receive call returns a message if there's one. If queue is empty, mq_receive() can wait for message or return with fail status, depending on O_NONBLOCK flag. There's alternate method to notify program by signal: a program calls mq_notify to subscribe on certain queue. Every time message is arrived in queue, the program gets a signal described in mq_notify() and can handle message asynchronously. 13

  14. Memory Mapping Memory Mapping Kernel has a paging mechanism. When memory is limited, some memory pages can be swapped out. When a program needs one of them: TLB produces page miss (no physical memory is provided for the virtual address); Kernel a loads corresponding page from disk and links to virtual memory page. If paging out a .text section, there is no need to provide a space on swap, because this data is already on disk e. g. in the binary program file, from which the process was started. More general process of mapping file to memory is called memory map. System call mmap asks kernel to map selected file to the virtual memory address range. After this done, the range can be used as an ordinary array filled with file's contents. The file has not to be read into memory completely, Linux use paging mechanism to represent corresponded file parts. 14

  15. Memory Mapping : System Calls Memory Mapping : System Calls Example of simple cat analog, that memory-maps file and than just writes it to stdout: #include <sys/mman.h> #include <sys/stat.h> #include <stdio.h> #include <fcntl.h> PROT_READ means that memory-mapped pages can only be read by the program MAP_PRIVATE means the program observe some fixed state of the file write to memory-mapped area does not change the file itself program supposes file can not be changed while memory-mapped in MAP_PRIVATE mode fstat is used to determine file size (it discovers other file properties as well) int main(int argc, char *argv[]) { char *addr; int fd; struct stat sb; fd = open(argv[1], O_RDONLY); fstat(fd, &sb); addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); fwrite(addr, 1, sb.st_size, stdout); return 0; } 15

  16. Shared Memory Shared Memory See page shm_overview at https://man7.org Multiple processes can have some of their virtual memory pages translated to the same physical page. Then they can communicate through this shared area called shared memory. POSIX shared memory implemented over memory-mapped file abstraction. First we need to open named shared memory object (shared memory analog of queue, shmobj for short). Programs can memory-map this object, read and write to it. 16

  17. Shared Memory : Create Shared Memory : Create Open named shared memory object (shared memory analog of queue, shmobj for short). Programs can mmap mmap this object, read and write to it. #include <stdio.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> #include <stdlib.h> Modes and permissions of the object are the same as when creating a queue. There is no sense in having newly created shmobj size other than zero, so ftruncate() call. int main(int argc, char *argv[]) { int fd; size_t size; void *addr; We call mmap() for declaring the object shared (with MAP_SHARED, of course). fd = shm_open(argv[1], O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR); size = atol(argv[2]); ftruncate(fd, size); addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); close(fd); return 0; 17 }

  18. Shared Memory : Write Shared Memory : Write To write to the shared memory, program opens shmobj, mmaps it and uses the memory as ordinary array #include <stdio.h> #include <fcntl.h> #include <sys/mman.h> #include <string.h> #include <unistd.h> There is no difference if you open shmobj for reading/writing or just writing, it is memory int main(int argc, char *argv[]) { int fd; size_t len; char *addr; The smobj descriptor only needed when opening shmobj, we can close it just after mmap() fd = shm_open(argv[1], O_RDWR, 0); len = strlen(argv[2]); ftruncate(fd, len); addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); close(fd); printf("Copying %d bytes\ \n n", len); memcpy(addr, argv[2], len); return 0; 18 }

  19. Shared Memory : Read Shared Memory : Read To read from shared memory, the program opens shmobj and tread it like mmapped file: #include <stdio.h> #include <fcntl.h> #include <sys/mman.h> #include <sys/stat.h> #include <unistd.h> Note fstat can be used to determine shared memory size as well as to determine file size int main(int argc, char *argv[]) { int fd; char *addr; struct stat sb; As usual, to stop using shmobj, one shall unlink it with shm_unlink(name) fd = shm_open(argv[1], O_RDONLY, 0); fstat(fd, &sb); addr = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); close(fd); fwrite(addr, 1, sb.st_size, stdout); printf("\ \n n Done"); return 0; 19 }

  20. Any Questions? Any Questions? 20

More Related Content

giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#