Lab 4
Lab 4
Lab 4
❀ This lab has been prepared to be conducted on UNIX-like operating systems (e.g.,
GNU/Linux Ubuntu). Please make sure to have a well-set-up environment. You will need
a computer, a GNU/Linux operating system, and a C-compiler ❀
Objective. During this lab, you will learn how to use the most important process manage-
ment system calls. You will be writing programs, using C-programming language, to create
new processes, terminate running processes, wait for processes (synchronization), change
the code segment of processes, and get the attributes of processes. The following POSIX
API system call primitives will be used:
2. exit(v): Terminates the process which executes the primitive and returns to the
parent process a one-byte integer value contained in the value of v.
3. wait(&status): When executed by a parent process, the later waits for its child pro-
cess termination notification. When a child process terminates, the primitive wait()
returns the PID of the child process which terminated. Also, it returns from the
address status (&status), the value sent by the exit primitive (see the value of v
in exit()), and the cause of the termination of its child process (concatenated in
two bytes). Basically, the most significant byte contains the value of v, and the
less significant byte carries the cause of the termination. You can use the macro
WIFEXITED(status) to retrieve the cause (1 normally terminated, otherwise abnor-
mally terminated) and WEXITSTATUS(status) to retrieve the value of v. Finally, if
there is no child to wait for, wait() returns -1.
4. getpid(): This primitive returns the value of the PID (Process IDentification num-
ber) of the process that executed it.
To use these primitives, make sure that your C-program includes the following header
files: <unistd.h>, <wait.h>, <sys/types.h>, and <stdlib.h>.
Task 1. Assume that we possess a multiprocessing computer and that we would like to
compute, using a computer program, the sum of a sequence from 0 to n (see equation below),
where n > 0. To speed up the computations, we would like to implement our program in
such a way so that we make use of multiprocessing. A simple intuition consists of dividing
the sum into two parts that will be run by two different processes. Let us say process P1
executes the sum from 0 to [ n2 ], and process P2 executes the sum from [ n2 ] + 1 to n. Process
P1 is set the task to display the final result. Exer 1.c is a typical implementation of this
scenario using the C-programming language under POSIX environment.
n
X
S= i = 0 + 1 + 2 + ··· + n
i=0
1. Compile and execute the program for different values (you may have to use the option
-lm to include the math.h library before compiling). Does the program perform the
correct computations? Explain.
Task 2. The program in eXer 2.c consists of one parent process that creates three other
child processes. Then, each child process, tries to execute the program count.c. By
executing the latter program, each process opens a shared file named nums.txt, reads the
stored value, increments it, then rewrites the new value back to the file, for 5000 times. By
compiling the program count.c using commands such as ($gcc count.c -o count.out)
and placing the output in the same directory (folder) as program eXer 2.c, then if each
of the three processes reads the value from the file nums.txt then increments that value
before writing it back to the file, in the normal circumstances, we should find at the end of
the execution that the file contains the value 15000 (5000 + 5000 + 5000).
1. Execute the program eXer 2.c multiple time and observe the final value that is stored
in the nums.txt file. Explain your observation (note that you should remove the file
nums.txt before re-executing the program).
2. What is the theoretically possible minimum value that could be stored in num.txt?
Explain.