0% found this document useful (0 votes)
10 views9 pages

Process Management with Fork() Examples

The document outlines several programming tasks involving the use of the fork() system call to manage processes. Each task requires the implementation of a program that handles user input, creates child processes, and demonstrates process communication by printing messages from both parent and child processes. The tasks include printing user-provided messages, simulating fixed process IDs, and performing calculations like product and factorial based on user input.

Uploaded by

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

Process Management with Fork() Examples

The document outlines several programming tasks involving the use of the fork() system call to manage processes. Each task requires the implementation of a program that handles user input, creates child processes, and demonstrates process communication by printing messages from both parent and child processes. The tasks include printing user-provided messages, simulating fixed process IDs, and performing calculations like product and factorial based on user input.

Uploaded by

Swathi Tamma
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

1 Problem Statement

Charlie is working on a program to illustrate how background processes


are managed using the fork() system call. His task is to write a program
that first prints a message, which is provided by the user at runtime. The
program should then create a background process that will pause for 5
seconds before finishing.

Once the background process completes its execution, the parent process
should print a message to indicate that the background process has
finished. If the program encounters any issues while creating the
background process, it should print an appropriate error message.

Charlie needs to ensure that the parent process correctly waits for the
child process to finish before displaying the final message. If the fork ()
system call fails, the program should report this failure.

Write a program to achieve the same.

Note:
Use the fork() method.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>

#define MAX_MESSAGE_LENGTH 100

int main() {
char message[MAX_MESSAGE_LENGTH];

// Get input message from the user


if (fgets(message, sizeof(message), stdin) == NULL) {
fprintf(stderr, "Error reading input.\n");
exit(EXIT_FAILURE);
}

// Remove trailing newline character if present


size_t len = strlen(message);
if (len > 0 && message[len - 1] == '\n') {
message[len - 1] = '\0';
}

// Print the user-provided message


printf("%s\n", message);

pid_t pid = fork();


if (pid == 0) {
// Child process
sleep(5);
exit(0);
} else if (pid > 0) {
// Parent process
wait(NULL);
printf("Background process has finished\n");
} else {
// Fork failed
fprintf(stderr, "Failed to create a background process\n");
exit(EXIT_FAILURE);
}

return 0;
}
2 Problem Statement

Leka is studying process management in her Operating Systems course and needs to create a
program to understand process creation and communication. She needs to implement a
program that demonstrates the use of the fork () system call to manage processes.

The program should:

 Read two messages from the user: one for the parent process and one for the child process.
 Create a child process using fork().
 The child process should print the message intended for it.
 The parent process should wait for the child process to finish and then print its own message.

Write a program to help Leka in implementing the same.


Input Format
The first line of input consists of a message representing the parent process.
The second line of input consists of a message representing the child process.
Output Format
The child process prints its message in the format: "Child Process Message: <message>".
The parent process prints its message in the format: "Parent Process Message: <message> "
after the child process completes.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <cstring>
#include <sys/wait.h>

#define MAX_MESSAGE_LENGTH 100

void forkexample(const char* parentMessage, const char* childMessage) {


pid_t p = fork();

if (p < 0) {
perror("fork failed");
exit(EXIT_FAILURE);
} else if (p == 0) {
printf("Child Process Message: %s\n", childMessage);
exit(EXIT_SUCCESS);
} else {
wait(NULL);
printf("Parent Process Message: %s\n", parentMessage);
}
}

int main() {
char parentMessage[MAX_MESSAGE_LENGTH],
childMessage[MAX_MESSAGE_LENGTH];

if (fgets(parentMessage, sizeof(parentMessage), stdin) == NULL) {


fprintf(stderr, "Error reading parent message.\n");
exit(EXIT_FAILURE);
}

size_t len = strlen(parentMessage);


if (len > 0 && parentMessage[len - 1] == '\n') {
parentMessage[len - 1] = '\0';
}

if (fgets(childMessage, sizeof(childMessage), stdin) == NULL) {


fprintf(stderr, "Error reading child message.\n");
exit(EXIT_FAILURE);
}

len = strlen(childMessage);
if (len > 0 && childMessage[len - 1] == '\n') {
childMessage[len - 1] = '\0';
}

forkexample(parentMessage, childMessage);

return 0;
}
1 Problem Statement

Neka, a junior software developer, is learning about process management. For her project,
she needs to simulate a parent-child process interaction using the fork () system call and
display fixed process IDs.

The program will prompt the user to enter an integer. It will then create a child process using
fork () that simulates its own process ID and the parent's process ID with predefined values.
The child process will output the integer received from the user, and after the child
completes, the parent process will show a message indicating that the child process has
finished.

Neka needs your help to complete this task.


Input Format
The input consists of a single integer.
Output Format
The output displays the result as follows

Child process output:

"Child process:"
"Child Process ID: X" where X is the fixed child process ID (5678).
"Parent Process ID: Y" where Y is the fixed parent process ID (1234).
"Received integer: Z" where Z is the integer input value provided by the user.
Parent process output:

"Parent process:"
"Parent Process ID: X"
"Child process finished executing."
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

// Define fixed process IDs for simulation


#define FIXED_PARENT_PID 1234
#define FIXED_CHILD_PID 5678

int main() {
int userInput;

// Get an integer input from the user


if (scanf("%d", &userInput) != 1) {
fprintf(stderr, "Invalid input. Please enter an integer.\n");
exit(EXIT_FAILURE);
}

// Create a child process


pid_t pid = fork();

if (pid < 0) {
// Fork failed
perror("fork");
exit(EXIT_FAILURE);
} else if (pid == 0) {
// Simulate child process with fixed PID
pid_t child_pid = FIXED_CHILD_PID;
pid_t parent_pid = FIXED_PARENT_PID;
printf("Child process:\n");
printf("Child Process ID: %d\n", child_pid);
printf("Parent Process ID: %d\n", parent_pid);
printf("Received integer: %d\n", userInput);
exit(EXIT_SUCCESS);
} else {
// Simulate parent process with fixed PID
pid_t parent_pid = FIXED_PARENT_PID;
wait(NULL); // Wait for the child process to complete
printf("Parent process:\n");
printf("Parent Process ID: %d\n", parent_pid);
printf("Child process finished executing.\n");
}

return 0;
}
2. Problem Statement

Kiruthick is tasked with implementing a program that simulates process


management using the fork () system call. The program will prompt the
user to input two integers. It will then create a child process that performs
two operations:

 Computes the product of the two integers.


 Calculates the factorial of the first integer.

The child process should display the calculated product and factorial along
with simulated fixed process IDs. After the child process completes, the
parent process will output a message indicating the completion of the
child process. The process IDs used in the simulation are fixed values.

Your task is to help Kiruthick in implementing the same.


Input Format
The input consists of two space-separated integers A and B.
Output Format
The output displays the result as follows

Child process output:


"Child process:"
"Child Process ID: {fixed_child_pid}"
"Parent Process ID: {fixed_parent_pid}"
"Product of {num1} and <num2>: {product}"
"Factorial of {num1}: {factorial_of_num1}"

Parent process output:


"Parent process:"
"Parent Process ID: {fixed_parent_pid}"
"Child process finished executing."
Refer to the sample output for the formatting specifications.
Constraints
The given test cases will fall under the following constraints:
The fixed process IDs for simulation are:
Parent Process ID: 1234
Child Process ID: 5678
1 ≤ A, B ≤ 20

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

#define FIXED_PARENT_PID 1234


#define FIXED_CHILD_PID 5678

long factorial(int n) {
if (n == 0 || n == 1)
return 1;
long result = 1;
for (int i = 2; i <= n; i++)
result *= i;
return result;
}

int main() {
int num1, num2;

if (scanf("%d %d", &num1, &num2) != 2) {


fprintf(stderr, "Invalid input. Please enter two integers.\n");
exit(EXIT_FAILURE);
}

pid_t pid = fork();

if (pid < 0) {
perror("fork");
exit(EXIT_FAILURE);
} else if (pid == 0) {
long factorial_num1 = factorial(num1);
int product = num1 * num2;
pid_t child_pid = FIXED_CHILD_PID;
pid_t parent_pid = FIXED_PARENT_PID;
printf("Child process:\n");
printf("Child Process ID: %d\n", child_pid);
printf("Parent Process ID: %d\n", parent_pid);
printf("Product of %d and %d: %d\n", num1, num2, product);
printf("Factorial of %d: %ld\n", num1, factorial_num1);
exit(EXIT_SUCCESS);
} else {
pid_t parent_pid = FIXED_PARENT_PID;
wait(NULL);
printf("Parent process:\n");
printf("Parent Process ID: %d\n", parent_pid);
printf("Child process finished executing.");
}

return 0;
}

Common questions

Powered by AI

The sources employ basic input validation, primarily checking if user input has been successfully read using functions like `fgets()` or `scanf()`. If inputs are not read correctly, error messages are printed, and the program is terminated using `exit(EXIT_FAILURE)`. Potential enhancements could include checking for whitespace-only input, handling input size limits more robustly to prevent buffer overflow risks, and using more sophisticated parsing to confirm that inputs fall within expected numerical or textual ranges. Additionally, implementing user prompts for re-entry of invalid inputs could improve user experience and data integrity .

The use of `exit()` in the given code sources contributes to the management of process lifecycles by explicitly terminating processes. In each child process, calling `exit()` directly after completing its assigned task ensures that the process ends cleanly and releases its resources. Similarly, if any error occurs during input reading or `fork()` failure, `exit()` is used to halt program execution with an error status. This usage of `exit()` ensures that processes do not continue executing unintended code paths and aids in preventing resource leaks, promoting clean process terminations .

The example programs use key system libraries to streamline process management tasks, such as `unistd.h` for the `fork()` and `sleep()` functions, `sys/types.h` and `sys/wait.h` for process control functions like `wait()`, and `stdlib.h` for standard library tools like `exit()`. These libraries provide direct access to system-level operations such as creating processes, managing their execution, and handling process termination. By offering these capabilities through standardized functions, the libraries enable programmers to implement complex process management tasks efficiently, maintaining portability and reliability across different systems .

In the provided sources, the parent process ensures proper termination of the child process by employing the `wait(NULL)` function call. This call makes the parent process pause and wait for the completion of the child process before proceeding with its execution. By using `wait(NULL)`, the parent process can ensure that it only prints its completion message after the child process has finished executing its task, thereby maintaining a synchronized flow and avoiding zombie processes, which occur when a child process terminates but remains in the process table .

The `fork()` system call is significant in process management as it is used to create a new process called the child process. This child process runs concurrently with the process that made the system call, known as the parent process. When `fork()` is called, the operating system creates a new process that is a duplicate of the parent process, with its own unique process identifier (PID). The child inherits most attributes from its parent but executes independently. This facilitates process creation in programming by allowing concurrent execution of processes, enabling tasks such as multitasking and parallel processing .

In Source 1, the program manages user input and output by first reading a string message from the user, which is then printed by the parent process. It creates a child process using `fork()`, and in this child process, the program pauses execution using `sleep()`. After the child process completes its task of sleeping for 5 seconds, it exits. The parent process uses `wait(NULL)` to ensure it waits for the child process to finish before printing a message indicating that the background process has completed .

Fixed process IDs are used in Source 3 to simulate and demonstrate process behavior in a controlled manner. By using predefined values for parent and child process IDs, such as 1234 and 5678, the program can consistently present the output of process interactions and computations, including process ID references, without relying on actual system-generated PIDs. This approach is beneficial for educational purposes or demonstrations where actual PIDs may vary each time the program is executed. It simplifies the observation of process relationships and output structure .

The error handling mechanism in the `fork()` system call involves checking the return value of the `fork()` function. If `fork()` returns a value less than 0, it indicates that the call to `fork()` failed, which typically occurs due to system limitations like resource exhaustion. In such cases, an error message is printed using `perror()`, and the program terminates using `exit(EXIT_FAILURE)`. This ensures that the program gracefully handles situations where processes cannot be created, preventing further errors or undefined behavior in the execution flow .

In Source 2, the program ensures message synchronization between processes using the `wait(NULL)` function call within the parent process. After the `fork()` call divides the execution into child and parent processes, the child process prints its designated message and exits. The parent process then waits for the child process to complete using `wait(NULL)`, ensuring that it only prints its message after the child has terminated. This method guarantees that the output sequence remains orderly as intended, with the child's message preceding the parent's .

In Source 3, the child process is assigned two computational tasks: calculating the product of two integers and computing the factorial of the first integer. After receiving the integers from the user input, the child process performs these operations using a function called `factorial()` for factorial computation and a simple multiplication operation for the product. The calculated values, along with simulated fixed process IDs, are then displayed by the child process before it exits. This structured execution demonstrates process management through parallel computations .

You might also like