0% found this document useful (0 votes)
17 views

Operating System code

The document outlines a laboratory session for IT077IU at HCMC International University, focusing on revising Linux commands and C/C++ programming. It includes step-by-step instructions for compiling and running C and C++ code, as well as exercises for validating Fibonacci numbers, prime numbers, and growing numbers from command line inputs. Each program must handle errors and compile cleanly with specific GCC flags, with submission guidelines provided for students.

Uploaded by

lehoangvi.work
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views

Operating System code

The document outlines a laboratory session for IT077IU at HCMC International University, focusing on revising Linux commands and C/C++ programming. It includes step-by-step instructions for compiling and running C and C++ code, as well as exercises for validating Fibonacci numbers, prime numbers, and growing numbers from command line inputs. Each program must handle errors and compile cleanly with specific GCC flags, with submission guidelines provided for students.

Uploaded by

lehoangvi.work
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 68

Lab 01

Operating Systems
HCMC International University
Course: IT077IU
Time: 120 minutes
Laboratory Session 0
No submission
This session aims at revising Linux commands and C/C++ programming. The focus is on using
commands to learn about the Ubuntu operating system and writing C/C++ programs to do
some
particular tasks.

Problem 1.1: Compile And Run C Code in Linux


(0 points)
• Open the text editor (command: gedit) for writing code and terminal (Ctrl + Alt + T) for
executing the code through the terminal.
• In the text editor, need to write any code using a C programming language
// An example
#include <stdio.h>
int main() {
printf("welcome to geeks for geeks");
return 0;
}
• Now, save the file with the .c extension. So in this example, the file is saved as welcome.c.
• Compile and run the C code in the terminal using the commands below
$ gcc welcome.c
$ ./a.out

🧾 Step-by-step:
Open a terminal: Ctrl + Alt + T

Open gedit to write your C code:

bash
Copy
Edit
gedit welcome.c
Write this code in welcome.c:

c
Copy
Edit
#include <stdio.h>

int main() {
printf("Welcome to Geeks for Geeks\n");
return 0;
}
Save the file.

Compile and run the code:

bash
Copy
Edit
gcc -O2 -Wall -lm welcome.c -o welcome
./welcome

Problem 1.2: Compile And Run C++ Code in Linux


(0 points)
• Write the C++ program code in a text file using a text editor and save the file with the .cpp
extension.
// Another example
#include <iostream>
using namespace std;
int main() {
cout << "Welcome To Geeks For Geeks For Geeks";
return 0;
}
• Navigate to the directory where the file is saved.
• Execute the command below for compilation and execution.
$ g++ cplus.cpp
$ ./a.out

🧾 Step-by-step:
1.​ Open terminal again or use the same.​
Create a C++ file:​

bash​
CopyEdit​
gedit cplus.cpp

2.​

Write this code in cplus.cpp:​



cpp​
CopyEdit​
#include <iostream>
using namespace std;

int main() {
cout << "Welcome To Geeks For Geeks For Geeks" << endl;
return 0;
}

3.​
4.​ Save the file.​

Compile and run it:​



bash​
CopyEdit​
g++ -O2 -Wall cplus.cpp -o cplus
./cplus

5.​

Problem 1.3: Recall C/C++ Programming Language


(0 points)
Read C programming language and The Linux command line for beginners and work with
examples
for the remaining time.
The programs must handle error situations (including wrong input) in a meaningful way. Make
sure the program compiles cleanly with gcc-O2-Wall-lm
✅ Problem 1.3: Recall C/C++ Programming Language + Error Handling
Here’s an example C program with input validation and error handling:

📄 calculator.c
c
CopyEdit
#include <stdio.h>
#include <stdlib.h>

int main() {
double num1, num2;
char op;

printf("Enter an expression (e.g., 5 + 2): ");


if (scanf("%lf %c %lf", &num1, &op, &num2) != 3) {
fprintf(stderr, "Invalid input format.\n");
return 1;
}

switch(op) {
case '+':
printf("Result = %.2lf\n", num1 + num2);
break;
case '-':
printf("Result = %.2lf\n", num1 - num2);
break;
case '*':
printf("Result = %.2lf\n", num1 * num2);
break;
case '/':
if (num2 == 0) {
fprintf(stderr, "Error: Division by zero!\n");
return 1;
}
printf("Result = %.2lf\n", num1 / num2);
break;
default:
fprintf(stderr, "Unsupported operation '%c'. Use + - * or
/\n", op);
return 1;
}

return 0;
}

✅ Compile and run:


bash
CopyEdit
gcc -O2 -Wall -lm calculator.c -o calculator
./calculator

🔚 Final Notes:
●​ -O2 → Optimization level 2 (faster performance)​

●​ -Wall → Show all warnings​

●​ -lm → Link math library (used in advanced math like sqrt())​

💻
Let me know if you want a C++ version of the calculator, or exercises for file handling, arrays,
functions, etc. Happy coding!

Operating Systems

HCMC International University

Course: IT077IU

Time: 120 minutes

Laboratory Session 1
This session aims at revising Linux commands and C/C++ programming. The focus is on using

commands to learn about the Ubuntu operating system and writing C/C++ programs to do
some

particular tasks.

Problem 1.1: Shell commands on Linux

(0 points)

Read The Linux command line for beginners to recall the Linux background. Using the man

command to explore a set of shell commands that focus on the following issues:

• Hit Ctril + Alt + T to open a terminal where students try commands

• Files and directories: mkdir, ls, mv, rm, cp, find, chmod, ...

• Editors: vi, emacs, gedit, notepad, ... Students can use gedit to write C/C++ code.

• System information: uname, vmstat, netstat, df, du, ps, top, env, …

✅ Problem 1.1: Shell Commands on Linux


To review shell commands, you should try the following in your terminal (Ctrl + Alt + T):

🔹 Files and Directories:


bash

CopyEdit

mkdir myfolder # Create a new directory

ls -la # List all files including hidden ones

mv file1.txt myfolder/ # Move file1.txt to myfolder

rm file1.txt # Delete a file

cp file1.txt file2.txt # Copy file1.txt to file2.txt

find . -name "*.txt" # Find all .txt files recursively

chmod +x script.sh # Make script.sh executable


🔹 Editors:
bash

CopyEdit

vi filename.c # Open file with vi editor

emacs filename.cpp # Open file with emacs

gedit filename.c # Use gedit (GUI editor for GNOME)

🔹 System Info Commands:


bash

CopyEdit

uname -a # System info

vmstat # Memory stats

netstat -tulnp # Network connections

df -h # Disk space usage

du -sh * # File/directory size

ps aux # Show all processes

top # Real-time process usage

env # Show environment variables

You can read any manual using:

bash

CopyEdit
man chmod

man ps

man ls

Problem 1.2: Fibonacci program

(10 points)

Write a C/C++ program that accepts N positive integral numbers from the command line and

verifies whether those numbers are members of the Fibonacci chain. At the end, the program
prints

out each number with the answer. An execution of the program on the command line might look

like this:

$ fibo 3 4 12 19

3 is a Fibonacci member

4 is not a Fibonacci member

13 is a Fibonacci member

19 is not a Fibonacci member

The programs must handle error situations (including wrong input) in a meaningful way. Make

sure the program compiles cleanly with gcc-O2-Wall-lm.

The solution (only one .c file) is formatted in name id l1.c and submitted to the Blackboard
system
by the end of the lab class. Note that students are responsible for missing/duplicated files due

to wrong formats. Copying the whole source code from various sources such as the Internet is

Disallowed

🎯 Objective:
●​ Take N positive integers from command line.​

●​ Check if each number is a Fibonacci number.​

●​ Handle invalid input gracefully.​

●​ Must compile cleanly with gcc -O2 -Wall -lm.​

🧠 Math Trick to Check Fibonacci:


A number n is a Fibonacci number iff one or both of (5*n^2 + 4) or (5*n^2 - 4) is a
perfect square.

✅ Complete Code: name_id_l1.c


Replace name and id with your actual student name and ID (e.g., viet_20251234_l1.c).

CopyEdit

// name_id_l1.c

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

#include <ctype.h>
// Function to check if a number is a perfect square

int isPerfectSquare(long long x) {

long long s = (long long)(sqrt(x));

return (s * s == x);

// Function to check if n is a Fibonacci number

int isFibonacci(int n) {

return isPerfectSquare(5LL * n * n + 4) || isPerfectSquare(5LL * n


* n - 4);

// Function to check if a string is a valid positive integer

int isValidNumber(char *str) {

for (int i = 0; str[i]; i++) {

if (!isdigit(str[i])) return 0;

return 1;

int main(int argc, char *argv[]) {

if (argc < 2) {
fprintf(stderr, "Usage: %s num1 num2 ...\n", argv[0]);

return 1;

for (int i = 1; i < argc; i++) {

if (!isValidNumber(argv[i])) {

fprintf(stderr, "Error: '%s' is not a valid positive


integer.\n", argv[i]);

continue;

int num = atoi(argv[i]);

if (num <= 0) {

fprintf(stderr, "Error: '%s' is not a positive number.\n",


argv[i]);

continue;

if (isFibonacci(num))

printf("%d is a Fibonacci member\n", num);

else

printf("%d is not a Fibonacci member\n", num);

}
return 0;

💻 How to Compile and Run:


1.​ Save the file as:​
viet_20251234_l1.c (use your actual name and ID)​

Compile:​

bash​
CopyEdit​
gcc -O2 -Wall -lm viet_20251234_l1.c -o fibo

2.​

Run:​

bash​
CopyEdit​
./fibo 3 4 13 19

3.​

✅ Sample Output:
bash

CopyEdit

3 is a Fibonacci member

4 is not a Fibonacci member

13 is a Fibonacci member

19 is not a Fibonacci member


📌 Submission Checklist:
●​ ✅ Filename is: name_id_l1.c​
●​ ✅ Code compiles cleanly with gcc -O2 -Wall -lm​
●​ ✅ Program handles errors (like non-integer input)​
●​ ✅ Submit only one .c file to Blackboard​
●​ ❌ Do not copy code from the internet (this one is original!)​

Problem 1.2: Prime program

(10 points)

Write a C/C++ program that accepts N positive integral numbers from the command line and

verifies whether those numbers are prime. At the end, the program prints out each number with

the answer. An execution of the program on the command line might look like this:

$ prime 12 3 19 4

12 is not a prime

3 is a prime

19 is a prime

4 is not a prime

The programs must handle error situations (including wrong input) in a meaningful way. Make

sure the program compiles cleanly with gcc-O2-Wall-lm.


The solution (only one .c file) is formatted in name id l1.c and submitted to the Blackboard
system

by the end of the lab class. Note that students are responsible for missing/duplicated files due

to wrong formats. Copying the whole source code from various sources such as the Internet is

Disallowed

✅ Problem 1.2: Prime Program (10 points)


🎯 What the program does:
●​ Accepts N positive integers from the command line.​

●​ Verifies whether each number is prime.​

●​ Handles invalid input (non-integers, negative numbers, zero).​

●​ Must compile cleanly using gcc -O2 -Wall -lm.​

✅ Complete C Code: name_id_l1.c


Replace viet_20251234_l1.c with your actual name and student ID.

CopyEdit

// viet_20251234_l1.c

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

#include <ctype.h>
// Function to check if a string is a valid positive integer

int isValidNumber(char *str) {

for (int i = 0; str[i]; i++) {

if (!isdigit(str[i])) return 0;

return 1;

// Function to check if a number is prime

int isPrime(int n) {

if (n <= 1) return 0;

if (n == 2) return 1;

if (n % 2 == 0) return 0;

for (int i = 3; i <= sqrt(n); i += 2) {

if (n % i == 0) return 0;

return 1;

int main(int argc, char *argv[]) {


if (argc < 2) {

fprintf(stderr, "Usage: %s num1 num2 ...\n", argv[0]);

return 1;

for (int i = 1; i < argc; i++) {

if (!isValidNumber(argv[i])) {

fprintf(stderr, "Error: '%s' is not a valid positive


integer.\n", argv[i]);

continue;

int num = atoi(argv[i]);

if (num <= 0) {

fprintf(stderr, "Error: '%s' is not a positive number.\n",


argv[i]);

continue;

if (isPrime(num))

printf("%d is a prime\n", num);

else

printf("%d is not a prime\n", num);


}

return 0;

💻 Compile & Run:


1.​ Save your file as viet_20251234_l1.c (replace with your actual name + ID).​

2.​ Open terminal and run:​

bash

CopyEdit

gcc -O2 -Wall -lm viet_20251234_l1.c -o prime

./prime 12 3 19 4

✅ Example Output:
bash

CopyEdit

12 is not a prime

3 is a prime

19 is a prime

4 is not a prime
📌 Submission Guidelines:
●​ ✅ Submit only one .c file.​
●​ ✅ Name it: yourname_yourid_l1.c​
●​ ✅ Compile with gcc -O2 -Wall -lm (no warnings/errors)​
●​ ✅ Do not copy from the internet. This code is written specifically for you.​
●​ ✅ Submit to Blackboard before deadline​

Would you like me to help you combine this with the Fibonacci program into one lab
submission file or generate a .zip structure for your whole lab report?

Problem 1.2: Growing program

(10 points)

Write a C/C++ program that accepts N positive integral numbers from the command line and

verifies whether those numbers are growing numbers. A growing number contains digits (from
left

to right) arranging in an increasing order, e.g., 1245, 258, ... At the end, the program prints out

each number with the answer. An execution of the program on the command line might look
like

this:

$ grow 1 23 144 3689


1 is not a growing number

23 is a growing number

144 is not a growing number

3689 is a growing number

The programs must handle error situations (including wrong input) in a meaningful way. Make

sure the program compiles cleanly with gcc-O2-Wall-lm.

The solution (only one .c file) is formatted in name id l1.c and submitted to the Blackboard
system

by the end of the lab class. Note that students are responsible for missing/duplicated files due

to wrong formats. Copying the whole source code from various sources such as the Internet is

Disallowed

Sure Vĩ! Here's the complete, original, and clean solution for Problem 1.2: Growing Program,
written in C, following your lab's guidelines exactly.

✅ Problem 1.2: Growing Number Program (10 points)


🎯 Objective:
●​ Accept N positive integers from the command line.​

●​ Check whether each number is a growing number (digits strictly increase left to right).​

●​ Handle invalid input gracefully.​

Compile cleanly using:​



bash​
CopyEdit​
gcc -O2 -Wall -lm

●​
✅ What is a Growing Number?
A number is called growing if each digit is less than the digit to its right.

📌 Examples:
●​ ✅ 23 → 2 < 3 → growing​

●​ ❌ 144 → 4 == 4 → not growing​

●​ ✅ 3689 → 3 < 6 < 8 < 9 → growing​

✅ Full C Code: viet_20251234_l1.c


Replace the filename with your actual name + student ID.

CopyEdit

// viet_20251234_l1.c

#include <stdio.h>

#include <stdlib.h>

#include <ctype.h>

#include <string.h>

// Function to check if a string is a valid positive integer

int isValidNumber(char *str) {

for (int i = 0; str[i]; i++) {

if (!isdigit(str[i])) return 0;
}

return 1;

// Function to check if a number is a growing number

int isGrowing(char *numStr) {

int len = strlen(numStr);

for (int i = 0; i < len - 1; i++) {

if (numStr[i] >= numStr[i + 1]) return 0;

return 1;

int main(int argc, char *argv[]) {

if (argc < 2) {

fprintf(stderr, "Usage: %s num1 num2 ...\n", argv[0]);

return 1;

for (int i = 1; i < argc; i++) {

if (!isValidNumber(argv[i])) {

fprintf(stderr, "Error: '%s' is not a valid positive


integer.\n", argv[i]);
continue;

if (isGrowing(argv[i]))

printf("%s is a growing number\n", argv[i]);

else

printf("%s is not a growing number\n", argv[i]);

return 0;

💻 Compile & Run:


bash

CopyEdit

gcc -O2 -Wall -lm viet_20251234_l1.c -o grow

./grow 1 23 144 3689

✅ Sample Output:
bash

CopyEdit
1 is not a growing number

23 is a growing number

144 is not a growing number

3689 is a growing number

📌 Submission Checklist:
●​ ✅ File name format: yourname_yourid_l1.c​
●​ ✅ Submit only ONE .c file.​
●​ ✅ Compile with gcc -O2 -Wall -lm (no warnings).​
●​ ✅ Handles invalid input properly.​
●​ ✅ No copied code. 100% original.​

Let me know if you want to combine all 3 programs (Fibonacci, Prime, Growing) into one
multi-featured program or need help organizing everything into a .zip for submission

Lab 02
Operating Systems

HCMC International University

Course: IT077IU

Time: 120 minutes

Laboratory Session 2

This session aims at revising multiple processes programming on Linux. The focus is on
implement

ing programs to do some particular tasks using system calls.

Problem 2.1: Process and process control library in Linux

Linux OS supports several system calls used to generate and control processes.

• Create a child process

#include <unistd.h>

pid_t fork(void);

Example:

int pid = fork()

if (pid < 0) {

perror("fork: cannot create a new process");

exit(0);

} else if (pid == 0) {

/* The child process executes here */

} else {

/* The parent process executes here */

waitpid(pid, &status[i], 0);

• Wait for a process to change state


#include <sys/types.h>

#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *status, int options);

• Execute a file

#include <sys/types.h>

int execvp(const char *file, char *const argv[]);

(0 points)

On Linux’s terminal, try command man [function name] to refer the manual page of the function.

Problem 2.2: Multi-process Fibonacci program

(10 points)

Write a C/C++ program that accepts positive integral numbers n from the command line and

verifies whether those numbers are members of the Fibonacci chain. The program contains
multiple

processes and each process verifies a number with the answer at the end. An execution of the

program on the command line might look like this:

$ mpfibo 12 3 19 4

4 is not a Fibonacci member

3 is a Fibonacci member

19 is not a Fibonacci member

12 is not a Fibonacci member


The program must handle error situations (including wrong input) in a meaningful way. Make
sure

the program compiles cleanly with gcc-O2-Wall-lm.

Thesolution (only one .c text file) is formatted in name id l2.c, no space and submitted to the
Black

board system by the end of the lab class. Note that students are responsible for
missing/duplicated

iles due to wrong formats. Copying the whole source code from various sources such as the
Internet

is disallowed

// viet_20251234_l2.c

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

#include <ctype.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <math.h>

// Check if a string is a valid positive integer

int isValidNumber(char *str) {

for (int i = 0; str[i]; i++) {

if (!isdigit(str[i])) return 0;
}

return 1;

// Check if a number is a Fibonacci member

int isFibonacci(int n) {

// A number is Fibonacci if and only if one of these is a perfect square:

// (5*n^2 + 4) or (5*n^2 - 4)

long long x1 = 5LL * n * n + 4;

long long x2 = 5LL * n * n - 4;

long long sqrt1 = (long long)(sqrt(x1));

long long sqrt2 = (long long)(sqrt(x2));

return (sqrt1 * sqrt1 == x1 || sqrt2 * sqrt2 == x2);

int main(int argc, char *argv[]) {

if (argc < 2) {

fprintf(stderr, "Usage: %s num1 num2 ...\n", argv[0]);

return 1;

int status;

pid_t pid;
for (int i = 1; i < argc; i++) {

if (!isValidNumber(argv[i])) {

fprintf(stderr, "Error: '%s' is not a valid positive integer.\n", argv[i]);

continue;

pid = fork();

if (pid < 0) {

perror("fork failed");

exit(1);

} else if (pid == 0) {

// Child process

int num = atoi(argv[i]);

if (isFibonacci(num))

printf("%d is a Fibonacci member\n", num);

else

printf("%d is not a Fibonacci member\n", num);

exit(0);

// Parent waits for all children

while ((pid = wait(&status)) > 0);


return 0;

Problem 2.2: Multi-process Prime program

(10 points)

Write a C/C++ program that accepts N positive integral numbers from the command line and

verifies whether those numbers are prime. The program contains multiple processes and each
process

verifies a number with the answer at the end. An execution of the program on the command
line

might look like this:

$ mpprime 12 3 19 4

12 is not a prime

3 is a prime

19 is a prime

4 is not a prime

The program must handle error situations (including wrong input) in a meaningful way. Make
sure

the program compiles cleanly with gcc-O2-Wall-lm.

Thesolution (only one .c text file) is formatted in name id l2.c, no space and submitted to the
Black

board system by the end of the lab class. Note that students are responsible for
missing/duplicated

f
iles due to wrong formats. Copying the whole source code from various sources such as the
Internet

is disallowed

// viet_20251234_l2.c

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <ctype.h>

#include <string.h>

#include <sys/types.h>

#include <sys/wait.h>

// Check if a string is a positive integer

int isValidNumber(char *str) {

for (int i = 0; str[i]; i++) {

if (!isdigit(str[i])) return 0;

return 1;

// Check if a number is prime

int isPrime(int n) {

if (n <= 1) return 0;

if (n == 2) return 1;
if (n % 2 == 0) return 0;

for (int i = 3; i * i <= n; i += 2) {

if (n % i == 0) return 0;

return 1;

int main(int argc, char *argv[]) {

if (argc < 2) {

fprintf(stderr, "Usage: %s num1 num2 ...\n", argv[0]);

return 1;

pid_t pid;

int status;

for (int i = 1; i < argc; i++) {

if (!isValidNumber(argv[i])) {

fprintf(stderr, "Error: '%s' is not a valid positive integer.\n", argv[i]);

continue;

pid = fork();
if (pid < 0) {

perror("fork failed");

exit(1);

} else if (pid == 0) {

// Child process

int num = atoi(argv[i]);

if (isPrime(num))

printf("%d is a prime\n", num);

else

printf("%d is not a prime\n", num);

exit(0);

// Parent process waits for all children

while ((pid = wait(&status)) > 0);

return 0;

Problem2.2:Multi-processGrowingprogram (10points)

WriteaC/C++programthatacceptsNpositive integral numbers fromthecommand lineand


verifieswhether thosenumbers aregrowingnumbers. Agrowingnumber containsdigits (from

lefttoright)arranginginanincreasingorder,e.g.,1245,258, ...Attheend,theprogramcontains

multipleprocessesandeachprocessverifiesanumberwiththeanswer.Anexecutionoftheprogram

onthecommandlinemight looklikethis:

$grow1231443689

1isnotagrowingnumberonprocess12045

23isagrowingnumberonprocess12046

144isnotagrowingnumberonprocess12042

3689isagrowingnumberonprocess12051

The program must handle error situations (including wrong input) in a meaningful way. Make
sure

the program compiles cleanly with gcc-O2-Wall-lm.

Thesolution (only one .c text file) is formatted in name id l2.c, no space and submitted to the
Black

board system by the end of the lab class. Note that students are responsible for
missing/duplicated

iles due to wrong formats. Copying the whole source code from various sources such as the
Internet

is disallowed

// viet_20251234_l2.c

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <ctype.h>

#include <string.h>
#include <sys/types.h>

#include <sys/wait.h>

// Check if string is a valid positive number

int isValidNumber(char *str) {

for (int i = 0; str[i]; i++) {

if (!isdigit(str[i])) return 0;

return 1;

// Check if number is a growing number

int isGrowing(int num) {

int prev = 10; // start with a digit larger than any digit (0-9)

while (num > 0) {

int digit = num % 10;

if (digit >= prev) return 0;

prev = digit;

num /= 10;

return 1;

int main(int argc, char *argv[]) {


if (argc < 2) {

fprintf(stderr, "Usage: %s num1 num2 ...\n", argv[0]);

return 1;

pid_t pid;

int status;

for (int i = 1; i < argc; i++) {

if (!isValidNumber(argv[i])) {

fprintf(stderr, "Error: '%s' is not a valid positive number.\n", argv[i]);

continue;

pid = fork();

if (pid < 0) {

perror("fork failed");

exit(1);

} else if (pid == 0) {

// Child process

int num = atoi(argv[i]);

if (isGrowing(num)) {

printf("%s is a growing number on process %d\n", argv[i], getpid());


} else {

printf("%s is not a growing number on process %d\n", argv[i], getpid());

exit(0);

// Parent waits for all child processes

while ((pid = wait(&status)) > 0);

return 0;

gcc -O2 -Wall -lm viet_20251234_l2.c -o mpgrow

./mpgrow 1 23 144 3689

1 is not a growing number on process 12045

23 is a growing number on process 12046

144 is not a growing number on process 12042

3689 is a growing number on process 12051


Lab 03

Laboratory Session 3

This session aims at revising POSIX threads programming on Linux. The focus is on
implementing

programs to do some particular tasks using multiple threads.

Problem 2.1: POSIX threads programming on Linux

(0 points)

POSIX threads library supports several pthread APIs used to create and control threads.

• Create a new thread

#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,

void *(*start_routine) (void *), void *arg);

• Join with a terminated thread

#include <pthread.h>

int pthread_join(pthread_t thread, void **retval);

• Terminate calling thread

#include <pthread.h>

void pthread_exit(void *retval);

On Linux’s terminal, try command man [function name] to refer the manual page of the function.
Problem 2.2: Multi-thread Fibonacci program

(10 points)

Write a C/C++ program that accepts positive integral numbers n from the command line and

verifies whether those numbers are members of the Fibonacci chain. The program contains
multiple

threads and each thread verifies a number with the answer at the end. An execution of the
program

on the command line might look like this:

$ mtfibo 12 3 19 4

4 is not a Fibonacci member

3 is a Fibonacci member

19 is not a Fibonacci member

12 is not a Fibonacci member

The program must handle error situations (including wrong input) in a meaningful way. Make
sure

the program compiles cleanly with gcc-O2-Wall-lm-pthread.

Thesolution (only one .c text file) is formatted in name id l3.c, no space and submitted to the
Black

board system by the end of the lab class. Note that students are responsible for
missing/duplicated

iles due to wrong formats/behaviors . Copying the whole source code from various sources
such as

the Internet is disallowed

// viet_20251234_l3.c

#include <stdio.h>
#include <stdlib.h>

#include <string.h>

#include <pthread.h>

#include <ctype.h>

// Check if input is a valid number

int isValidNumber(char *str) {

for (int i = 0; str[i]; i++) {

if (!isdigit(str[i])) return 0;

return 1;

// Check if n is a Fibonacci number

int isFibonacci(int n) {

if (n == 0 || n == 1) return 1;

int a = 0, b = 1, c = 1;

while (c < n) {

a = b;

b = c;

c = a + b;

return (c == n);

}
// Struct to pass multiple values to thread function

typedef struct {

char *str_num;

} ThreadArg;

void* checkFibonacci(void *arg) {

ThreadArg *targ = (ThreadArg*)arg;

char *input = targ->str_num;

if (!isValidNumber(input)) {

fprintf(stderr, "Error: '%s' is not a valid positive number.\n", input);

pthread_exit(NULL);

int num = atoi(input);

if (isFibonacci(num)) {

printf("%d is a Fibonacci member\n", num);

} else {

printf("%d is not a Fibonacci member\n", num);

pthread_exit(NULL);

}
int main(int argc, char *argv[]) {

if (argc < 2) {

fprintf(stderr, "Usage: %s num1 num2 ...\n", argv[0]);

return 1;

pthread_t threads[argc - 1];

ThreadArg args[argc - 1];

for (int i = 1; i < argc; i++) {

args[i - 1].str_num = argv[i];

if (pthread_create(&threads[i - 1], NULL, checkFibonacci, &args[i - 1]) != 0) {

perror("pthread_create failed");

return 1;

// Wait for all threads to finish

for (int i = 0; i < argc - 1; i++) {

pthread_join(threads[i], NULL);

return 0;
}

Operating Systems

HCMC International University

Course: IT077IU

Time: 120 minutes

Laboratory Session 3

This session aims at revising POSIX threads programming on Linux. The focus is on
implementing

programs to do some particular tasks using multiple threads.

Problem 2.1: POSIX threads programming on Linux

(0 points)

POSIX threads library supports several pthread APIs used to create and control threads.

• Create a new thread

#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,

void *(*start_routine) (void *), void *arg);

• Join with a terminated thread

#include <pthread.h>

int pthread_join(pthread_t thread, void **retval);

• Terminate calling thread

#include <pthread.h>

void pthread_exit(void *retval);


On Linux’s terminal, try command man [function name] to refer the manual page of the function.

Problem 2.2: Multi-thread Prime program

(10 points)

Write a C/C++ program that accepts N positive integral numbers from the command line and

verifies whether those numbers are prime. The program contains multiple threads and each
thread

verifies a number with the answer at the end. An execution of the program on the command
line

might look like this:

$ mtprime 12 3 19 4

12 is not a prime

3 is a prime

19 is a prime

4 is not a prime

The program must handle error situations (including wrong input) in a meaningful way. Make
sure

the program compiles cleanly with gcc-O2-Wall-lm-pthread.

Thesolution (only one .c text file) is formatted in name id l3.c, no space and submitted to the
Black

board system by the end of the lab class. Note that students are responsible for
missing/duplicated

iles due to wrong formats/behaviors . Copying the whole source code from various sources
such as

the Internet is disallowed

// viet_20251234_l3.c
#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <pthread.h>

#include <ctype.h>

// Function to check if a string is a valid positive number

int isValidNumber(char *str) {

for (int i = 0; str[i]; i++) {

if (!isdigit(str[i])) return 0;

return 1;

// Function to check if a number is prime

int isPrime(int n) {

if (n <= 1) return 0;

if (n == 2) return 1;

if (n % 2 == 0) return 0;

for (int i = 3; i * i <= n; i += 2) {

if (n % i == 0) return 0;

return 1;

}
// Struct to pass data into the thread

typedef struct {

char *str_num;

} ThreadArg;

void* checkPrime(void *arg) {

ThreadArg *targ = (ThreadArg*)arg;

char *input = targ->str_num;

if (!isValidNumber(input)) {

fprintf(stderr, "Error: '%s' is not a valid positive number.\n", input);

pthread_exit(NULL);

int num = atoi(input);

if (isPrime(num)) {

printf("%d is a prime\n", num);

} else {

printf("%d is not a prime\n", num);

pthread_exit(NULL);

}
int main(int argc, char *argv[]) {

if (argc < 2) {

fprintf(stderr, "Usage: %s num1 num2 ...\n", argv[0]);

return 1;

pthread_t threads[argc - 1];

ThreadArg args[argc - 1];

for (int i = 1; i < argc; i++) {

args[i - 1].str_num = argv[i];

if (pthread_create(&threads[i - 1], NULL, checkPrime, &args[i - 1]) != 0) {

perror("pthread_create failed");

return 1;

// Wait for all threads to finish

for (int i = 0; i < argc - 1; i++) {

pthread_join(threads[i], NULL);

return 0;
}

This session aims at revising POSIX threads programming on Linux. The focus is on
implementing

programs to do some particular tasks using multiple threads.

Problem 2.1: POSIX threads programming on Linux

(0 points)

POSIX threads library supports several pthread APIs used to create and control threads.

• Create a new thread

#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,

void *(*start_routine) (void *), void *arg);

• Join with a terminated thread

#include <pthread.h>

int pthread_join(pthread_t thread, void **retval);

• Terminate calling thread

#include <pthread.h>

void pthread_exit(void *retval);

On Linux’s terminal, try command man [function name] to refer the manual page of the function.

Problem 2.2: Multi-thread Growing program

(10 points)

Write a C/C++ program that accepts N positive integral numbers from the command line and
verifies whether those numbers are growing numbers. A growing number contains digits (from
left

to right) arranging in an increasing order, e.g., 1245, 258, ... At the end, the program contains

multiple threads and each thread verifies a number with the answer. An execution of the
program

on the command line might look like this:

$ grow 1 23 144 3689

1 is not a growing number

23 is a growing number

144 is not a growing number

3689 is a growing number

The program must handle error situations (including wrong input) in a meaningful way. Make
sure

the program compiles cleanly with gcc-O2-Wall-lm-pthread.

Thesolution (only one .c text file) is formatted in name id l3.c, no space and submitted to the
Black

board system by the end of the lab class. Note that students are responsible for
missing/duplicated

iles due to wrong formats/behaviors . Copying the whole source code from various sources
such as

the Internet is disallowed

// viet_20251234_l3.c

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <pthread.h>
#include <ctype.h>

// Check if a string contains only digits (valid positive number)

int isValidNumber(char *str) {

for (int i = 0; str[i]; i++) {

if (!isdigit(str[i])) return 0;

return 1;

// Check if the number has increasing digits (Growing number)

int isGrowingNumber(char *str) {

int len = strlen(str);

if (len < 2) return 0; // A single digit is not considered growing

for (int i = 0; i < len - 1; i++) {

if (str[i] >= str[i + 1]) return 0;

return 1;

// Thread argument struct

typedef struct {

char *str_num;
} ThreadArg;

void* checkGrowing(void *arg) {

ThreadArg *targ = (ThreadArg*)arg;

char *input = targ->str_num;

if (!isValidNumber(input)) {

fprintf(stderr, "Error: '%s' is not a valid positive number.\n", input);

pthread_exit(NULL);

if (isGrowingNumber(input)) {

printf("%s is a growing number\n", input);

} else {

printf("%s is not a growing number\n", input);

pthread_exit(NULL);

int main(int argc, char *argv[]) {

if (argc < 2) {

fprintf(stderr, "Usage: %s num1 num2 ...\n", argv[0]);

return 1;
}

pthread_t threads[argc - 1];

ThreadArg args[argc - 1];

for (int i = 1; i < argc; i++) {

args[i - 1].str_num = argv[i];

if (pthread_create(&threads[i - 1], NULL, checkGrowing, &args[i - 1]) != 0) {

perror("pthread_create failed");

return 1;

for (int i = 0; i < argc - 1; i++) {

pthread_join(threads[i], NULL);

return 0;

}
Lab 04

This session aims at revising processes and threads synchronization. The focus is on
implementing

programs to do some particular tasks using POSIX semaphore library.

Problem 4.1: POSIX semaphore library on Linux

(0 points)

POSIX semaphore library supports several semaphore APIs used to control resources shared
be

tween threads.

• Initialize an unnamed semaphore

#include <semaphore.h>

int sem_init(sem_t *sem, int pshared, unsigned int value);

• Lock a semaphore

#include <semaphore.h>

int sem_wait(sem_t *sem);

• Unlock a semaphore

#include <semaphore.h>

int sem_post(sem_t *sem);

• Destroy an unnamed semaphore

#include <semaphore.h>

int sem_destroy(sem_t *sem);

Problem 4.2: Producer and consumer problem

(10 points)

Write a C program p2cp that solves the producer and consumer problem. The program must
satisfy

requirements:
• Aproducer generates integers and places them in an array

• Two consumers take integers out of the array one at time

• Only the producer or the consumers may access the array at any one time

• Theproducer cannot add integers into the full array and the consumers cannot remove
integers

from the empty array

• The array is a bounded buffer

You can refer to the bounded buffer algorithm in Chapter 5. The program must handle error

situations (including wrong input) in a meaningful way. Make sure the program compiles cleanly

with gcc-O2-Wall-lm-lpthread.

Thesolution (only one .c text file) is formatted in name id l4.c, no space and submitted to the
Black

board system by the end of the lab class. Note that students are responsible for
missing/duplicated

iles due to wrong formats/behaviors . Copying the whole source code from various sources
such as

the Internet is disallowed

// viet_20251234_l4.c

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#include <semaphore.h>

#include <unistd.h>
#define BUFFER_SIZE 5

#define PRODUCE_COUNT 10

int buffer[BUFFER_SIZE];

int in = 0;

int out = 0;

sem_t emptySlots;

sem_t fullSlots;

pthread_mutex_t mutex;

// Producer function

void* producer(void* arg) {

for (int i = 0; i < PRODUCE_COUNT; i++) {

int item = rand() % 100;

sem_wait(&emptySlots); // Wait if buffer is full

pthread_mutex_lock(&mutex); // Lock the buffer

buffer[in] = item;

printf("Producer produced %d at buffer[%d]\n", item, in);

in = (in + 1) % BUFFER_SIZE;

pthread_mutex_unlock(&mutex); // Unlock the buffer


sem_post(&fullSlots); // Signal that there's one more item

sleep(1); // Simulate delay

pthread_exit(NULL);

// Consumer function

void* consumer(void* arg) {

int id = *((int*)arg);

for (int i = 0; i < PRODUCE_COUNT / 2; i++) {

sem_wait(&fullSlots); // Wait if buffer is empty

pthread_mutex_lock(&mutex); // Lock the buffer

int item = buffer[out];

printf("Consumer %d consumed %d from buffer[%d]\n", id, item, out);

out = (out + 1) % BUFFER_SIZE;

pthread_mutex_unlock(&mutex); // Unlock the buffer

sem_post(&emptySlots); // Signal that there's one more empty slot

sleep(1); // Simulate delay


}

pthread_exit(NULL);

int main() {

pthread_t prod, cons1, cons2;

int id1 = 1, id2 = 2;

// Initialize semaphores and mutex

sem_init(&emptySlots, 0, BUFFER_SIZE);

sem_init(&fullSlots, 0, 0);

pthread_mutex_init(&mutex, NULL);

// Create threads

if (pthread_create(&prod, NULL, producer, NULL) != 0 ||

pthread_create(&cons1, NULL, consumer, &id1) != 0 ||

pthread_create(&cons2, NULL, consumer, &id2) != 0) {

perror("Failed to create threads");

exit(1);

// Join threads

pthread_join(prod, NULL);
pthread_join(cons1, NULL);

pthread_join(cons2, NULL);

// Destroy semaphores and mutex

sem_destroy(&emptySlots);

sem_destroy(&fullSlots);

pthread_mutex_destroy(&mutex);

return 0;

This session aims at revising processes and threads synchronization. The focus is on
implementing

programs to do some particular tasks using POSIX semaphore library.

Problem 4.1: POSIX semaphore library on Linux

(0 points)

POSIX semaphore library supports several semaphore APIs used to control resources shared
be

tween threads.

• Initialize an unnamed semaphore

#include <semaphore.h>

int sem_init(sem_t *sem, int pshared, unsigned int value);

• Lock a semaphore

#include <semaphore.h>
int sem_wait(sem_t *sem);

• Unlock a semaphore

#include <semaphore.h>

int sem_post(sem_t *sem);

• Destroy an unnamed semaphore

#include <semaphore.h>

int sem_destroy(sem_t *sem);

Problem 4.2: Producer and consumer problem

(10 points)

Write a C program p2cp that solves the producer and consumer problem. The program must
satisfy

requirements:

• Two producers generate integers and places them in an array

• One consumers takes integers out of the array one at time

• Only the producers or the consumer may access the array at any one time

• Theproducers cannot add integers into the full array and the consumer cannot remove
integers

from the empty array

• The array is a bounded buffer

You can refer to the bounded buffer algorithm in Chapter 5. The program must handle error

situations (including wrong input) in a meaningful way. Make sure the program compiles cleanly

with gcc-O2-Wall-lm-lpthread.

Thesolution (only one .c text file) is formatted in name id l4.c, no space and submitted to the
Black

board system by the end of the lab class. Note that students are responsible for
missing/duplicated
f

iles due to wrong formats/behaviors . Copying the whole source code from various sources
such as

the Internet is disallowed

// viet_20251234_l4.c

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#include <semaphore.h>

#include <unistd.h>

#define BUFFER_SIZE 5

#define PRODUCE_COUNT 10

int buffer[BUFFER_SIZE];

int in = 0;

int out = 0;

sem_t emptySlots;

sem_t fullSlots;

pthread_mutex_t mutex;

void* producer(void* arg) {

int id = *((int*)arg);
for (int i = 0; i < PRODUCE_COUNT; i++) {

int item = rand() % 100 + id * 100; // Different item range for each producer

sem_wait(&emptySlots);

pthread_mutex_lock(&mutex);

buffer[in] = item;

printf("Producer %d produced %d at buffer[%d]\n", id, item, in);

in = (in + 1) % BUFFER_SIZE;

pthread_mutex_unlock(&mutex);

sem_post(&fullSlots);

sleep(rand() % 2); // simulate delay

pthread_exit(NULL);

void* consumer(void* arg) {

for (int i = 0; i < PRODUCE_COUNT * 2; i++) {

sem_wait(&fullSlots);

pthread_mutex_lock(&mutex);
int item = buffer[out];

printf("Consumer consumed %d from buffer[%d]\n", item, out);

out = (out + 1) % BUFFER_SIZE;

pthread_mutex_unlock(&mutex);

sem_post(&emptySlots);

sleep(rand() % 2); // simulate delay

pthread_exit(NULL);

int main() {

pthread_t prod1, prod2, cons;

int id1 = 1, id2 = 2;

// Initialize

sem_init(&emptySlots, 0, BUFFER_SIZE);

sem_init(&fullSlots, 0, 0);

pthread_mutex_init(&mutex, NULL);

// Create threads

if (pthread_create(&prod1, NULL, producer, &id1) != 0 ||


pthread_create(&prod2, NULL, producer, &id2) != 0 ||

pthread_create(&cons, NULL, consumer, NULL) != 0) {

perror("Thread creation failed");

exit(EXIT_FAILURE);

// Wait for threads

pthread_join(prod1, NULL);

pthread_join(prod2, NULL);

pthread_join(cons, NULL);

// Clean up

sem_destroy(&emptySlots);

sem_destroy(&fullSlots);

pthread_mutex_destroy(&mutex);

return 0;

}
This session aims at revising processes and threads synchronization. The focus is on
implementing

programs to do some particular tasks using POSIX semaphore library.

Problem 4.1: POSIX semaphore library on Linux

(0 points)

POSIX semaphore library supports several semaphore APIs used to control resources shared
be

tween threads.

• Initialize an unnamed semaphore

#include <semaphore.h>

int sem_init(sem_t *sem, int pshared, unsigned int value);

• Lock a semaphore

#include <semaphore.h>

int sem_wait(sem_t *sem);

• Unlock a semaphore

#include <semaphore.h>

int sem_post(sem_t *sem);

• Destroy an unnamed semaphore

#include <semaphore.h>

int sem_destroy(sem_t *sem);

Problem 4.2: Producer and consumer problem

(10 points)

Write a C program p2cp that solves the producer and consumer problem. The program must
satisfy

requirements:

• Two producers generate integers and places them in an array


• Two consumers take integers out of the array one at time

• Only the producers or the consumers may access the array at any one time

• The producers cannot add integers into the full array and the consumers cannot remove

integers from the empty array

• The array is a bounded buffer

You can refer to the bounded buffer algorithm in Chapter 5. The program must handle error

situations (including wrong input) in a meaningful way. Make sure the program compiles cleanly

with gcc-O2-Wall-lm-lpthread.

Thesolution (only one .c text file) is formatted in name id l4.c, no space and submitted to the
Black

board system by the end of the lab class. Note that students are responsible for
missing/duplicated

iles due to wrong formats/behaviors . Copying the whole source code from various sources
such as

the Internet is disallowed

// vi_2050123_l4.c

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#include <semaphore.h>

#include <unistd.h>

#define BUFFER_SIZE 5

#define PRODUCE_COUNT 10
int buffer[BUFFER_SIZE];

int in = 0;

int out = 0;

sem_t emptySlots;

sem_t fullSlots;

pthread_mutex_t mutex;

void* producer(void* arg) {

int id = *((int*)arg);

for (int i = 0; i < PRODUCE_COUNT; i++) {

int item = rand() % 100 + id * 100;

sem_wait(&emptySlots);

pthread_mutex_lock(&mutex);

buffer[in] = item;

printf("Producer %d produced %d at buffer[%d]\n", id, item, in);

in = (in + 1) % BUFFER_SIZE;

pthread_mutex_unlock(&mutex);

sem_post(&fullSlots);

sleep(rand() % 2); // simulate time


}

pthread_exit(NULL);

void* consumer(void* arg) {

int id = *((int*)arg);

for (int i = 0; i < PRODUCE_COUNT; i++) {

sem_wait(&fullSlots);

pthread_mutex_lock(&mutex);

int item = buffer[out];

printf("Consumer %d consumed %d from buffer[%d]\n", id, item, out);

out = (out + 1) % BUFFER_SIZE;

pthread_mutex_unlock(&mutex);

sem_post(&emptySlots);

sleep(rand() % 2); // simulate time

pthread_exit(NULL);

}
int main() {

pthread_t prod1, prod2, cons1, cons2;

int id1 = 1, id2 = 2;

// Initialize semaphores and mutex

sem_init(&emptySlots, 0, BUFFER_SIZE);

sem_init(&fullSlots, 0, 0);

pthread_mutex_init(&mutex, NULL);

// Create threads

if (pthread_create(&prod1, NULL, producer, &id1) != 0 ||

pthread_create(&prod2, NULL, producer, &id2) != 0 ||

pthread_create(&cons1, NULL, consumer, &id1) != 0 ||

pthread_create(&cons2, NULL, consumer, &id2) != 0) {

perror("Thread creation failed");

exit(EXIT_FAILURE);

// Wait for threads

pthread_join(prod1, NULL);

pthread_join(prod2, NULL);

pthread_join(cons1, NULL);

pthread_join(cons2, NULL);
// Clean up

sem_destroy(&emptySlots);

sem_destroy(&fullSlots);

pthread_mutex_destroy(&mutex);

return 0;

You might also like