System and Device Programming Laboratory number 01 (System and Programming part) Learning goals -------------- Operating system basics, more specifically: processes, signals, pipes, threads, and synchronization system calls. Exercise 01 (Optional) The UNIX file system ---------------------- An ASCII file has lines with the following format: - An identifier, i.e., an integer value varying from 1 to the number of rows in the file (e.g., 1, 2, etc.) - A register number, i.e., a long integer of 6 digits (e.g., 164678) - A surname, i.e., a string of maximum 30 characters (e.g., Rossi) - A name, i.e., a string of maximum 30 characters (e.g., Mario) - An examination mark, i.e., an integer value. The following is a correct example of such a file: 1 100000 Romano Antonio 25 2 150000 Fabrizi Aldo 22 3 200000 Verdi Giacomo 15 4 250000 Rossi Luigi 30 Write a C program (l01e01) in UNIX which is run with 3 file names on the command line, i.e., l01file file_input_1 file_output_1 file_output_2 and which it is able to: - Read the *text* file file_input_1 (with the previous format) and copy it into file file_output_1 in *binary* format and with *fixed-length* records (integer + long integer + 31 characters + 31 characters + integer). - Read back the *binary* file file_output_1 and store it as a *text* into file file_output_2. - Verify that files file_input_1 and file_output_2 are indeed equivalent using the shell command "wc" (word count). Suggestions ----------- - Manipulate text files using C library function - Manipulate binary files using the I/O UNIX library Exercise 02 (Optional) UNIX signals ---------------------- Write a C program that is able to handle signals as described by the following specifications. The program accepts signals SIGUSR1 and SIGUSR2, and: - It displays a success message every time it receives a signal SIGUSR1 followed by a signal SIGUSR2, or viceversa. - It displays an error message every time it receives two signals SIGUSR1 or two signals SIGUSR2 consecutively. - It terminates if it receives three successive SIGUSR1 or SIGUSR2 signals. Suggestion ----------- Once it is compiled, run the program in background (...&) and use the shell command "kill" to send signal SIGUSR1 and SIGUSR2 to the process. Exercise 03 (Optional) UNIX pipes ---------------------- Two processes P1 and P2 want to exchange data using a file such that the information written by P1 into the file are read by P2 and vice-versa. To be able to read and write the same file, P1 and P2 must synchronize their operations, and they decided to do that using a pipe. Write a program which is able to do the following. A file stores a set of strings, one string on each file row. - Process P1 starts, and process P2 awaits. Process P1 does the following step: - It reads the file - It displays the file content on standard output - It reads a new set of new strings from standard input and it stores them into the same file; the string "end" stops the input phase - After that process P2 starts and process P2 waits. Process P2 operates as process P1. Both processes must terminate in a correct way when the string "END" is introduced from standard input to one of the two process. Exercise 04 UNIX Processes -------------- A binary number of size n can be easily generated by a recursive function like the one reported in file ex04recursive.c Transform the recursive program into a concurrent one, replacing the recursive procedure with the generation of an appropriate number of *processes*. Each process must display one binary numbers. Binary number can be displayed in any order. For example, if n=3, the function must generate and print numbers: 000, 001, 010, 011, 100, 101, 110, 111 IN ANY ORDER. Exercise 05 UNIX threads ------------ Implement a C program, thread_generation, that receives a command line parameter n. The parent thread creates two threads and waits for their termination. Each further thread creates other two threads, and it awaits for their termination. Tread creation stops after 2^n threads have been created, i.e., the ones that stand on the leaves of a tree with 2^n leaves. For example, if n=3 - the main thread creates two threads - each one of these 2 threads creates other two threads, - each one of these 4 threads creates other two threads at this point 8 leaf treads are running and the program must stop. Each leaf thread must print its generation tree, i.e., the sequence of thread identifiers from the main thread (the tree root) to the leaf thread (tree leaf). The following is an example of the program execution: quer@quer-VirtualBox:~/current/sdp$ ./l01e05 3 140051327870720 140051311085312 140051224717056 140051327870720 140051311085312 140051224717056 140051327870720 140051311085312 140051233109760 140051327870720 140051319478016 140051207931648 140051327870720 140051311085312 140051233109760 140051327870720 140051319478016 140051207931648 140051327870720 140051319478016 140051216324352 140051327870720 140051319478016 140051216324352 Suggestion ---------- Print (and store) thread identifiers (tids) as "long integer" values. Exercise 06 UNIX threads and semaphores --------------------------- Implements a concurrent C program, using semaphores, that: - Generates one producer and one consumer thread, and it awaits for their termination. - The producer threads produces, one at a time, 1000 integer numbers (from 0 to 999), and it puts each of them in a shared circular buffer of dimension BUFFER_SIZE (constant value, e.g., equal to 16), and finally puts -1. - The consumer thread gets each number from the shared buffer, and it saves the number in file "out.txt". It terminates after reading -1. Verify that indeed file "out.txt" contains 1000 numbers, and that the consumer thread receives these numbers in the correct order. Suggestion ---------- Use the standard producer and consumer scheme with 1 single producer and 1 single consumer.