Table of Contents
Solution of exercises (Exam 2020/09/14 with exams platform)
Return to Operating Systems Course
Download text of exercises: 20200914e.pdf - exams platform
Solution
Textual solution: 20200914e_sol.pdf - exams platform
Video with the solution of all the exercises of the exam
Solution exercise 2
Text:
Explain why:
- Two processes can or cannot share a global variable.
- Two threads can or cannot share a global variable.
Solution:
- During the generation of a new process, for instance by means of the system call fork(), the address space is duplicated and therefore disjoint.
- Threads share the same address space, as a consequence a write operation on a global variable by means of a thread has effect on all the other threads
Solution exercise 4
Text:
- Explain the effect of running the system call exec from a UNIX program.
- Explain what differentiate the “l”, “v”, “p” and “e” versions.
- Make an example of how the “v” and the “l” version can be used.
- Why the system call exec should not return?
Solution:
- The exec system call replaces the program associated with a process (code, data, etc.) with another one specified as a parameter, without replacing the PID (Process IDentifier) of the initial process.
- It basically changes the prototype of the function and what it receives as input:
- l: list → the function receives a list of arguments.
- v: vector → the function receives a vector of arguments.
- p: path → the function receives only the name of the file (without the path). The file is searched by browsing the list of directories stored in the environment variable with name PATH.
- e: environment → the function receives a vector containing a list of environment variables.
- Example execv:
char *cmd[] = {“ls”, “-l”, (char *)0};
execv(“/bin/ls”, cmd);
Example execl:
execl(“/bin/ls”, “ls”, “-l”, NULL); - The system call exec does not return to the caller program if executed with success. In the case of error, exec (in all its variants) returns -1.
Solution exercise 6
Text:
A program initializes a semaphore named sem to N, and then it allows at most N threads entering the critical section CS using in all threads the following prologue and epilogue:
sem_wait (&sem); CS sem_post (&sem);
Re-implement the same prologue and epilogue using only 2 mutexes as synchronization strategies. Please, remind and use only the following synchronization system calls.
int pthread_mutex_lock (pthread_mutex_t *mutex); int pthread_mutex_unlock (pthread_mutex_t *mutex);
Solution:
Two mutexes were used: m1 and m2. m1 was initialized as unlocked (i.e., 1), while m2 was initialized as locked (i.e., 0).
int n = 0; pthread_mutex_lock(&m1); n++; if (n > N) { pthread_mutex_unlock(&m1); pthread_mutex_lock(&m2); } else { pthread_mutex_unlock(&m1); } CS pthread_mutex_lock(&m1); n--; if (n >= N) pthread_mutex_unlock(&m2); pthread_mutex_unlock(&m1);
Solution exercise 7
Text:
Specify what happens if a thread attempts to:
- read from a pipe, but all file descriptors referring to the write end of a pipe have been closed.
- write to a pipe, but all file descriptors referring to the read end of a pipe have been closed.
Solution:
- If all file descriptors referring to the write-end of a pipe have been closed, then an attempt to read from the pipe will see end-of-file (read returns 0).
- If all file descriptors referring to the read-end of a pipe have been closed, then a write to the pipe will cause a SIGPIPE signal to be generated for the calling process. The default action of SIGPIPE is the termination of the process.
Solution exercise 8
Text:
A program executes a very high number of threads T, but in order not to exceed the hardware resources globally available on the server, it forces a specific piece of code (called SC) to be executed simultaneously by a maximum of N threads (with N « T). To achieve this behavior, the programmer defines a semaphore sem initialized to the value N, and then he allows access to SC only through the following section of code:
sem_wait (sem); SC sem_post (sem);
Suppose that later on, the programmer wants to run some other threads that consume twice the hardware resources of the former threads, thus he wants to make each thread access to SC in place of one thread of the first type. The programmer's idea is to manage the access to SC of these threads through the following piece of code:
sem_wait (sem); sem_wait (sem); SC sem_post (sem); sem_post (sem);
Anyhow, after writing the previous piece of code, the programmer realizes that it presents a fundamental problem in a system in which some original and latter types of threads are running simultaneously. Indicate this problem and how it can be corrected.
Solution:
The problem of the proposed solution is the possibility of deadlock. If all the N threads execute the first sem_wait() before the second sem_wait() is executed by at least one of them, they would be blocked because no thread could enter the critical section (CS), and consequently execute the sem_post(), which allows other threads to enter the critical section.
A possible solution is to make both sem_wait() “atomic”, i.e. by using mutual exclusion:
sem_wait(ME); sem_wait(sem); sem_wait(sem); sem_post(ME); CS sem_post(sem); sem_post(sem);
with ME initialized to 1.
Solution exercise 10
Text:
Produce a bash script that requires in input the name of a file containing alphabetic characters, and raises an error if the script is run with an incorrect number of parameters. The program must transform lines with an even number of words into capital letters, and lines with an odd number of words into lowercase letters. For instance, if the file “file.txt” has the following content:
- file.txt
Nel mezzo del Cammin di Nostra vita mi ritrovai per una Selva oscura
The output of the command:
> ./prog.sh file.txt
must be the following:
nel mezzo del CAMMIN DI NOSTRA VITA MI RITROVAI PER UNA SELVA OSCURA
In particular, the first line has been transformed into lowercase letters because it consists of 3 words, while the remaining lines have been transformed into uppercase letters because they consist of 2, 6 and 2 words, respectively.
- 20200914e_ex10.sh
#!/bin/bash # Exam 2020/09/14 - Exercise 10 # Check correct number of parameters if [ $# -lt 1 ]; then echo "Usage: ./prog.sh <FILE>" exit 1 fi # Read file line by line while read line; do # Compute number of words in line n=$(echo $line | wc -w) # If line has an odd number of words convert it to lower case if [ $[$n%2] -eq 1 ]; then echo $line | tr [A-Z] [a-z] fi # If line has an even number of words convert it to upper case if [ $[$n%2] -eq 0 ]; then echo $line | tr [a-z] [A-Z] fi done < $1 exit 0
If you found any error, or if you want to partecipate to the editing of this wiki, please contact: admin [at] skenz.it
You can reuse, distribute or modify the content of this page, but you must cite in any document (or webpage) this url: https://www.skenz.it/os/20200914e_sol