Process Interaction
2024-12-19
Questions? Answered by the Praxisreferat
Updates can be found on campUAS in the courses
Practical phase Computer Science and Computer Science - Mobile Applications
Why do processes need to interact?
call each other,
wait for each other, or
coordinate with each other
What about threads?
Process X | Process Y | |
next_free_slot = in; (Result: 16) |
||
Process | ||
switch | ||
next_free_slot = in; (Result: 16) |
||
Store record in next_free_slot; (Result: 16) |
||
in = next_free_slot + 1; (Result: 17) |
||
Process | ||
switch | ||
Store record in next_free_slot; (Result: 16) |
||
in = next_free_slot + 1; (Result: 17) |
The spooling directory is consistent
Such a situation is called race condition
How can processes communicate?
stdin
, stdout
, and stderr
)RIOT Since most microcontrollers do not provide a \(\rightarrow\) MMU all processes can typically access all memory regions …
Linux/UNIX operating systems contain a shared memory table, which contains information about the existing shared memory segments
Shared memory objects are accessed similar to files
When the operating system is rebooted, the shared memory segments and their contents are lost
A buffered unidirectional communication channel between two processes (\(\Rightarrow\) simplex FIFO)
One process accesses the write end, the other the read end of the pipe
Has a limited capacity and can block on both ends:
pipe()
read()
and write()
system calls (or standard library functions) similar to filesfork()
, the child processes also inherit access to the file descriptorsfork()
can communicate with each other via anonymous pipesOverview of the pipes in Linux/UNIX: lsof | grep pipe
mkfifo("<pathname>",<permissions>)
Creating a Socket:
socket()
Binding a socket to a port number and making it ready to receive data:
bind()
, listen()
, accept()
and connect()
Sending/receiving messages via the socket:
send()
, sendto()
, recv()
and recvfrom()
Closing of a socket:
shutdown()
or close()
Overview of the sockets in Linux/UNIX: netstat -n
or lsof | grep socket
Examples of Interprocess communication via sockets (TCP and UDP) in Linux can be found on the website of this course
socket
)sendto
) and receive data (recvfrom
)close
)socket
)bind
)sendto
) and receive data (recvfrom
)close
)socket
)connect
)send
) and receive data (recv
)close
)socket
)bind
)listen
)
accept
)
send
) and receive data (recv
)close
)Shared Memory | Message Queues | (anon./named) | Sockets | |
Pipes | ||||
Scheme | Memory-based | Message-based | Stream-based | Message-based |
Bidirectional | yes | no | no | yes |
Platform independent | no | no | no | yes |
Processes relation required | no | no | for anon. pipes | no |
Common address space required | yes | yes | yes | no |
Bound to a process | no | on | yes | yes |
Automatic synchronization | no | yes | yes | yes |
Advantages of message-based communication versus memory-based communication:
The operating system takes care about the synchronization of accesses \(\Longrightarrow\) comfortable
Can be used in distributed systems without a shared memory
Better portability of applications
Storage can be integrated via network connections
What is required if process \(P_A\) needs to process X before process \(P_B\) can do Y?
Used to specify an execution order
Example: Section X of process \(P_{A}\) must be executed before section Y of process \(P_{B}\)
signal
operation signals that process \(P_{A}\) has finished section Xs
wait
operation occupies the processor at regular intervalsWhat can be done if the order of execution is not important?
In order to protect critical sections, i.e., no overlap in their execution, locking can be used
In contrast to signaling the execution order is not specified
The necessary operations are lock
and unlock
What may go wrong?
Source: https://i.redd.it/vvu6v8pxvue11.jpg
(author and license: unknown)
Limitations of deadlock detection with resource graphs
Only individual resources (i.e., no copies) can be represented
Source of the example: Tanenbaum. Moderne Betriebssysteme. Pearson. 2009
\[\mbox{Existing resource vector} = \left(\begin{array}{cccc}4 & 2 & 3 & 1 \end{array}\right)\]
\[\mbox{Available resource vector} = \left(\begin{array}{cccc}2 & 1 & 0 & 0 \end{array}\right)\]
\[\mbox{Current allocation matrix} = \left[\begin{array}{cccc} 0 & 0 & 1 & 0 \\ 2 & 0 & 0 & 1 \\ 0 & 1 & 2 & 0 \\ \end{array}\right]\]
\[\mbox{Request matrix} = \left[\begin{array}{cccc} 2 & 0 & 0 & 1 \\ 1 & 0 & 1 & 0 \\ 2 & 1 & 0 & 0 \\ \end{array}\right]\]
\[\mbox{Available resource vector} = \left(\begin{array}{cccc} 2 & 2 & 2 & 0 \end{array}\right)\]
\[\mbox{Request matrix} = \left[\begin{array}{cccc} 2 & 0 & 0 & 1 \\ 1 & 0 & 1 & 0 \\ - & - & - & - \\ \end{array}\right]\]
\[\mbox{Available resource vector} = \left(\begin{array}{cccc} 4 & 2 & 2 & 1 \end{array}\right)\]
\[\mbox{Request matrix} = \left[\begin{array}{cccc} 2 & 0 & 0 & 1 \\ - & - & - & - \\ - & - & - & - \\ \end{array}\right]\]
Cooperating sequential processes. Edsger W. Dijkstra (1965) https://www.cs.utexas.edu/~EWD/ewd01xx/EWD123.PDF
A Semaphore consists of 2 Data Structures
COUNT
: An integer, non-negative counter variable.
Specifies how many processes can pass the semaphore now without getting blocked
A waiting room
for the processes, which wait until they are allowed to pass the semaphore
The processes are in blocked
state until they are transferred into ready
state by the operating system when the semaphore allows to access the critical section
Initialization: First, a new semaphore is created or an existing one is opened
// apply the INIT operation on semaphore SEM
SEM.INIT(unsigned int init_value) {
// initialize the variable COUNT of Semaphor SEM
// with a non-negative initial value
SEM.COUNT = init_value;
}
SEM.P() {
// if the counter variable = 0, the process becomes blocked
if (SEM.COUNT == 0)
< block >
// if the counter variable is > 0, the counter variable
// is decremented immediately by 1
SEM.COUNT = SEM.COUNT - 1;
}
Image Source: Carsten Vogt
SEM.V() {
// counter variable = counter variable + 1
SEM.COUNT = SEM.COUNT + 1;
// if processes are in the waiting room, one gets unblocked
if ( < SEM waiting room is not empty > )
< unblock a waiting process >
}
Image Source: Carsten Vogt
Source: Kenneth Baclawski (Northeastern University in Boston), Image Source: Michael Vigneau (license: unknown)
http://www.ccs.neu.edu/home/kenb/tutorial/example.gif
Three semaphores are used to synchronize access to the buffer
empty
filled
mutex
The semaphores filled
and empty
are used in opposite to each other
empty
counts the number of empty locations in the buffer and its value is reduced by the producer (P operation) and raised by the consumer (V operation)
empty
= 0 \(\Longrightarrow\) buffer is completely filled \(\Longrightarrow\) producer is blockedfilled
counts the number of data packets (occupied locations) in the buffer and its value is raised by the producer (V operation) and reduced by the consumer (P operation)
filled
= 0 \(\Longrightarrow\) buffer is empty \(\Longrightarrow\) consumer is blockedThe semaphore mutex
is used to ensure for the mutual exclusion
Binary Semaphores
mutex
from the producer/consumer exampletypedef int semaphore; // semaphores are of type integer
semaphore filled = 0; // counts the number of occupied locations in the buffer
semaphore empty = 8; // counts the number of empty locations in the buffer
semaphore mutex = 1; // controls access to the critial sections
void producer (void) {
int data;
while (TRUE) { // infinite loop
createDatapacket(data); // create data packet
P(empty); // decrement the empty locations counter
P(mutex); // enter the critical section
insertDatapacket(data); // write data packet into the buffer
V(mutex); // leave the critical section
V(filled); // increment the occupied locations counter
}
}
void consumer (void) {
int data;
while (TRUE) { // infinite loop
P(filled); // decrement the occupied locations counter
P(mutex); // enter the critical section
removeDatapacket(data); // pick data packet from the buffer
V(mutex); // leave the critical section
V(empty); // increment the empty locations counter
consumeDatapacket(data); // consume data packet
}
}
Image Source: Carsten Vogt
Linux/UNIX operating systems provide three system calls for working with System V semaphores
semget()
: Create new semaphore or a group of semaphores or open an existing semaphoresemctl()
: Request or modify the value of an existing semaphore or of a semaphore group or erase a semaphoresemop()
: Carry out P and V operations on semaphoresipcs
Several implementations of the mutex concept exist
C standard library: mtx_init
, mtx_unlock
(V operation), mtx_lock
(P operation), mtx_trylock
, mtx_timedlock
, mtx_destroy
POSIX threads: pthread_mutex_init
, pthread_mutex_unlock
, pthread_mutex_lock
, pthread_mutex_trylock
, pthread_mutex_timedlock
, pthread_mutex_destroy
C standard library (Sun/Oracle Solaris): mutex_init
, mutex_unlock
, mutex_lock
, mutex_trylock
, mutex_destroy
Information about existing System V shared memory segments, System V message queues, and System V semaphores provides the command ipcs
The easiest way to erase such shared memory segments, message queues and semaphores from the command line is the command ipcrm
ipcrm [-m shmid] [-q msqid] [-s semid]
[-M shmkey] [-Q msgkey] [-S semkey]
POSIX memory segments and POSIX semaphores can be inspected and manually erased in the directory /dev/shm
POSIX message queues can be inspected and manually erased in the directory /dev/mqueue
You should now be able to answer the following questions:
Operating Systems - Process Interaction - WS 24/25