0% found this document useful (0 votes)
8 views16 pages

RTOS Programs Using C Language in LINUX OS

The document provides examples of C programs for creating child processes and multithreaded applications in Linux. It covers using fork for process creation, semaphores for thread synchronization, shared memory for inter-thread communication, and message queues for data exchange between threads. Each section includes code snippets and explanations for implementing these concepts effectively.

Uploaded by

kruthits
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)
8 views16 pages

RTOS Programs Using C Language in LINUX OS

The document provides examples of C programs for creating child processes and multithreaded applications in Linux. It covers using fork for process creation, semaphores for thread synchronization, shared memory for inter-thread communication, and message queues for data exchange between threads. Each section includes code snippets and explanations for implementing these concepts effectively.

Uploaded by

kruthits
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/ 16

RTOS programs using C language in LINUX OS.

Develop programs to (a) create child process


and display its id and (b) Execute child process function using switch structure
ChatGPT

To write RTOS (Real-Time Operating System) programs in C for Linux, you'll typically use the
POSIX API for process management. Let's go through the tasks one by one.

(a) Create a child process and display its ID

In this task, we will create a child process using the fork() system call and then display its ID.

Here's a simple example:

c
Copy code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

int main() {
pid_t pid;

// Create a child process


pid = fork();

if (pid < 0) { // Error occurred


fprintf(stderr, "Fork Failed\n");
return 1;
}
else if (pid == 0) { // Child process
printf("Child Process: My PID is %d\n", getpid());
}
else { // Parent process
printf("Parent Process: My child's PID is %d\n", pid);
wait(NULL); // Wait for child process to complete
}

return 0;
}

(b) Execute child process function using switch structure

Here, we extend the previous example to execute a specific function in the child process using a
switch structure.

c
Copy code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
// Function prototypes
void child_function();

int main() {
pid_t pid;

// Create a child process


pid = fork();

switch(pid) {
case -1: // Error occurred
fprintf(stderr, "Fork Failed\n");
return 1;

case 0: // Child process


printf("Child Process: My PID is %d\n", getpid());
child_function(); // Execute child function
break;

default: // Parent process


printf("Parent Process: My child's PID is %d\n", pid);
wait(NULL); // Wait for child process to complete
break;
}

return 0;
}

void child_function() {
printf("Child Process: Executing child function\n");
// Add more functionality here if needed
}

Explanation

1. Creating a Child Process:


o fork() is used to create a child process.
o pid will be 0 in the child process and the child's PID in the parent process.
2. Switch Structure:
o The switch statement is used to handle different cases based on the value of pid.
o case -1 handles the error when fork() fails.
o case 0 is for the child process where a specific function (child_function()) is
executed.
o The default case is for the parent process where it waits for the child to
complete.
3. Child Function:
o The child_function() is called in the child process to demonstrate executing a
specific task.

This basic structure can be extended to implement more complex RTOS-like functionalities in
Linux.
4o
Develop and test program for a multithreaded application, where communication is through a
buffer forthe conversion of lowercase text to uppercase text, using semaphore concept.
ChatGPT

To create a multithreaded application where communication occurs through a buffer for


converting lowercase text to uppercase text using semaphores, we need to:

1. Set up a shared buffer.


2. Use two threads: one for producing (reading and converting text to uppercase) and
another for consuming (printing the converted text).
3. Use semaphores to manage synchronization between the producer and consumer threads.

Here's a complete C program to achieve this:

c
Copy code
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <ctype.h>
#include <string.h>

#define BUFFER_SIZE 1024

// Shared buffer
char buffer[BUFFER_SIZE];

// Semaphores
sem_t empty;
sem_t full;

// Function prototypes
void *producer(void *param);
void *consumer(void *param);

int main() {
pthread_t tid1, tid2; // Thread identifiers

// Initialize semaphores
sem_init(&empty, 0, 1);
sem_init(&full, 0, 0);

// Create threads
pthread_create(&tid1, NULL, producer, NULL);
pthread_create(&tid2, NULL, consumer, NULL);

// Wait for threads to finish


pthread_join(tid1, NULL);
pthread_join(tid2, NULL);

// Destroy semaphores
sem_destroy(&empty);
sem_destroy(&full);

return 0;
}

void *producer(void *param) {


char input[BUFFER_SIZE];

printf("Enter a string to convert to uppercase: ");


fgets(input, BUFFER_SIZE, stdin);

// Remove newline character from input


input[strcspn(input, "\n")] = 0;

// Wait until buffer is empty


sem_wait(&empty);

// Convert input to uppercase and copy to buffer


for (int i = 0; input[i] != '\0'; i++) {
buffer[i] = toupper(input[i]);
}

// Signal that the buffer is full


sem_post(&full);

pthread_exit(0);
}

void *consumer(void *param) {


// Wait until buffer is full
sem_wait(&full);

// Print the content of the buffer


printf("Converted string: %s\n", buffer);

// Signal that the buffer is empty


sem_post(&empty);

pthread_exit(0);
}

Explanation

1. Shared Buffer:
o A buffer of size BUFFER_SIZE is used to hold the converted text.
2. Semaphores:
o Two semaphores, empty and full, are used to manage synchronization between
the producer and consumer threads.
o empty semaphore ensures the buffer is empty before the producer can write to it.
o full semaphore ensures the buffer is full before the consumer can read from it.
3. Producer Thread:
o Reads input from the user.
o Converts the input text to uppercase.
o
Copies the converted text to the shared buffer.
o
Signals the consumer thread that the buffer is full by posting to the full
semaphore.
4. Consumer Thread:
o Waits for the full semaphore, indicating that the buffer has data.
o Prints the converted text from the buffer.
o Signals the producer thread that the buffer is empty by posting to the empty
semaphore.

Compilation and Execution

To compile and run this program:

1. Save the code in a file, say multithreaded_conversion.c.


2. Open a terminal and navigate to the directory containing the file.
3. Compile the program using gcc:

bash
Copy code
gcc -pthread -o multithreaded_conversion multithreaded_conversion.c

4. Run the executable:

bash
Copy code
./multithreaded_conversion

You should see a prompt to enter a string, and after entering it, the converted uppercase string
will be displayed.

4o
Develop and test program for a multithreaded application, where communication is through
sharedmemory for the conversion of lowercase text to uppercase text.
ChatGPT

To create a multithreaded application that uses shared memory for communication between
threads to convert lowercase text to uppercase text, we need to:

1. Set up a shared memory region.


2. Create two threads: one for reading input and converting it to uppercase (producer), and
another for printing the converted text (consumer).
3. Use mutexes and condition variables for synchronization.

Here's a complete C program to achieve this:

c
Copy code
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <ctype.h>
#include <string.h>

#define BUFFER_SIZE 1024

// Shared buffer and flag


char buffer[BUFFER_SIZE];
int buffer_full = 0;

// Mutex and condition variables


pthread_mutex_t mutex;
pthread_cond_t cond;

// Function prototypes
void *producer(void *param);
void *consumer(void *param);

int main() {
pthread_t tid1, tid2; // Thread identifiers

// Initialize mutex and condition variables


pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);

// Create threads
pthread_create(&tid1, NULL, producer, NULL);
pthread_create(&tid2, NULL, consumer, NULL);

// Wait for threads to finish


pthread_join(tid1, NULL);
pthread_join(tid2, NULL);

// Destroy mutex and condition variables


pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);

return 0;
}

void *producer(void *param) {


char input[BUFFER_SIZE];

printf("Enter a string to convert to uppercase: ");


fgets(input, BUFFER_SIZE, stdin);

// Remove newline character from input


input[strcspn(input, "\n")] = 0;

// Lock the mutex


pthread_mutex_lock(&mutex);

// Convert input to uppercase and copy to shared buffer


for (int i = 0; input[i] != '\0'; i++) {
buffer[i] = toupper(input[i]);
}
buffer[strlen(input)] = '\0'; // Null-terminate the string
buffer_full = 1;

// Signal the consumer thread


pthread_cond_signal(&cond);

// Unlock the mutex


pthread_mutex_unlock(&mutex);

pthread_exit(0);
}

void *consumer(void *param) {


// Lock the mutex
pthread_mutex_lock(&mutex);

// Wait until the buffer is full


while (!buffer_full) {
pthread_cond_wait(&cond, &mutex);
}

// Print the content of the buffer


printf("Converted string: %s\n", buffer);

// Unlock the mutex


pthread_mutex_unlock(&mutex);

pthread_exit(0);
}

Explanation

1. Shared Buffer and Flag:


o A buffer of size BUFFER_SIZE is used to hold the converted text.
o buffer_full is a flag to indicate whether the buffer contains valid data.
2. Mutex and Condition Variables:
o A mutex (pthread_mutex_t mutex) is used to ensure mutual exclusion when
accessing the shared buffer.
o A condition variable (pthread_cond_t cond) is used to signal the consumer
thread when the buffer is full.
3. Producer Thread:
o Reads input from the user.
o Converts the input text to uppercase.
o Copies the converted text to the shared buffer.
o Signals the consumer thread that the buffer is full by broadcasting the condition
variable.
o Unlocks the mutex to allow the consumer thread to proceed.
4. Consumer Thread:
o Waits for the signal indicating that the buffer is full.
o Prints the converted text from the buffer.
Compilation and Execution

To compile and run this program:

1. Save the code in a file, say multithreaded_conversion.c.


2. Open a terminal and navigate to the directory containing the file.
3. Compile the program using gcc:

bash
Copy code
gcc -pthread -o multithreaded_conversion multithreaded_conversion.c

4. Run the executable:

bash
Copy code
./multithreaded_conversion

You should see a prompt to enter a string, and after entering it, the converted uppercase string
will be displayed.

4o
Develop program for inter-thread communication using message queue.Data is to be input from
the keyboard for the chosen application.
ChatGPT

To develop a program for inter-thread communication using a message queue, we'll create a
multithreaded application where one thread reads input from the keyboard and sends it to a
message queue, and another thread reads from the message queue and processes the data.

We'll use the POSIX message queue API in Linux for this purpose. Here's a step-by-step
implementation:

1. Create a message queue.


2. Create two threads: one for producing messages (reading input) and another for
consuming messages (processing input).
3. Use the message queue for communication between the producer and consumer threads.

Here's a complete C program to achieve this:

c
Copy code
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <mqueue.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <ctype.h>

#define QUEUE_NAME "/message_queue"


#define QUEUE_SIZE 10
#define MESSAGE_SIZE 1024
#define MAX_MESSAGES 10

// Function prototypes
void *producer(void *param);
void *consumer(void *param);

int main() {
pthread_t tid1, tid2; // Thread identifiers

// Create message queue attributes


struct mq_attr attr;
attr.mq_flags = 0;
attr.mq_maxmsg = MAX_MESSAGES;
attr.mq_msgsize = MESSAGE_SIZE;
attr.mq_curmsgs = 0;

// Create message queue


mqd_t mq = mq_open(QUEUE_NAME, O_CREAT | O_RDWR, 0644, &attr);
if (mq == (mqd_t) -1) {
perror("mq_open");
exit(EXIT_FAILURE);
}

// Create threads
pthread_create(&tid1, NULL, producer, NULL);
pthread_create(&tid2, NULL, consumer, NULL);

// Wait for threads to finish


pthread_join(tid1, NULL);
pthread_join(tid2, NULL);

// Close and unlink message queue


mq_close(mq);
mq_unlink(QUEUE_NAME);

return 0;
}

void *producer(void *param) {


mqd_t mq;
char message[MESSAGE_SIZE];

// Open message queue


mq = mq_open(QUEUE_NAME, O_WRONLY);
if (mq == (mqd_t) -1) {
perror("mq_open");
pthread_exit(NULL);
}

// Read input from the user


printf("Enter a string to convert to uppercase: ");
fgets(message, MESSAGE_SIZE, stdin);
// Remove newline character from input
message[strcspn(message, "\n")] = 0;

// Send message to the message queue


if (mq_send(mq, message, strlen(message) + 1, 0) == -1) {
perror("mq_send");
mq_close(mq);
pthread_exit(NULL);
}

mq_close(mq);
pthread_exit(NULL);
}

void *consumer(void *param) {


mqd_t mq;
char message[MESSAGE_SIZE];
char converted_message[MESSAGE_SIZE];

// Open message queue


mq = mq_open(QUEUE_NAME, O_RDONLY);
if (mq == (mqd_t) -1) {
perror("mq_open");
pthread_exit(NULL);
}

// Receive message from the message queue


if (mq_receive(mq, message, MESSAGE_SIZE, NULL) == -1) {
perror("mq_receive");
mq_close(mq);
pthread_exit(NULL);
}

// Convert message to uppercase


for (int i = 0; message[i] != '\0'; i++) {
converted_message[i] = toupper(message[i]);
}

// Print the converted message


printf("Converted string: %s\n", converted_message);

mq_close(mq);
pthread_exit(NULL);
}

Explanation

1. Message Queue Attributes:


o struct mq_attr is used to define the attributes of the message queue, such as
maximum message size and the maximum number of messages.
2. Message Queue Creation:
o mq_open() is used to create and open a message queue. The message queue is
created with read and write permissions (O_CREAT | O_RDWR).
3. Producer Thread:
o Opens the message queue with write-only permissions (O_WRONLY).
o Reads input from the user.
o Sends the input message to the message queue using mq_send().
4. Consumer Thread:
o Opens the message queue with read-only permissions (O_RDONLY).
o Receives the message from the message queue using mq_receive().
o Converts the message to uppercase.
o Prints the converted message.
5. Main Function:
o Initializes the message queue attributes.
o Creates the producer and consumer threads.
o Waits for the threads to complete.
o Closes and unlinks the message queue to clean up resources.

Compilation and Execution

To compile and run this program:

1. Save the code in a file, say multithreaded_message_queue.c.


2. Open a terminal and navigate to the directory containing the file.
3. Compile the program using gcc:

bash
Copy code
gcc -o multithreaded_message_queue multithreaded_message_queue.c -
lpthread -lrt

4. Run the executable:

bash
Copy code
./multithreaded_message_queue

You should see a prompt to enter a string. After entering the string, the consumer thread will
process and print the converted uppercase string.

4o
Create 'n' number of child threads. Each thread prints the message "I'm in thread number
sleepsfor 50 ms and then quits. The main thread waits for complete execution of all the child
threads and then quits.
ChatGPT

To create a program that spawns n child threads, where each thread prints a message, sleeps for
50 milliseconds, and then quits, while the main thread waits for all child threads to complete, you
can use the following C program with the pthread library.
Here’s a complete example:

c
Copy code
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

void *print_message(void *thread_id);

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


if (argc != 2) {
fprintf(stderr, "Usage: %s <number of threads>\n", argv[0]);
return 1;
}

int n = atoi(argv[1]);
pthread_t threads[n];
int thread_ids[n];

// Create n threads
for (int i = 0; i < n; i++) {
thread_ids[i] = i + 1;
int rc = pthread_create(&threads[i], NULL, print_message, (void
*)&thread_ids[i]);
if (rc) {
fprintf(stderr, "Error: Unable to create thread %d\n", i);
return 1;
}
}

// Wait for all threads to complete


for (int i = 0; i < n; i++) {
pthread_join(threads[i], NULL);
}

printf("Main thread: All child threads have completed.\n");


return 0;
}

void *print_message(void *thread_id) {


int id = *((int *)thread_id);
printf("I'm in thread number %d\n", id);
usleep(50000); // Sleep for 50 milliseconds
pthread_exit(NULL);
}

Explanation

1. Command-line Argument:
o The program expects the number of threads (n) as a command-line argument.
o If the argument is not provided, it prints a usage message and exits.
2. Thread Creation:
oThe main function reads the number of threads from the command line.
oIt then creates an array of pthread_t to hold the thread identifiers and an array of
integers to hold thread IDs.
o It loops n times, creating a thread in each iteration with pthread_create(). Each
thread runs the print_message function and receives its ID as an argument.
3. Thread Function (print_message):
o Each thread prints its ID.
o The thread then sleeps for 50 milliseconds using usleep(50000).
o The thread exits with pthread_exit(NULL).
4. Main Thread:
o After creating all the threads, the main thread waits for each of them to complete
using pthread_join().
o Once all threads have completed, the main thread prints a message and exits.

Compilation and Execution

To compile and run this program:

1. Save the code in a file, say multithreaded_sleep.c.


2. Open a terminal and navigate to the directory containing the file.
3. Compile the program using gcc:

bash
Copy code
gcc -o multithreaded_sleep multithreaded_sleep.c -lpthread

4. Run the executable with the desired number of threads, for example:

bash
Copy code
./multithreaded_sleep 5

This will create 5 threads, each printing its message, sleeping for 50 milliseconds, and then
quitting. The main thread will wait for all child threads to complete before printing its final
message and exiting.

4o
Implement the usage of anonymous pipe with 512 bytes for data sharing between parent and
child processes using handle inheritance mechanism.
ChatGPT

To implement an anonymous pipe with a buffer size of 512 bytes for data sharing between parent
and child processes using the handle inheritance mechanism in C, we need to:

1. Create an anonymous pipe.


2. Fork the process to create a parent and a child process.
3. Use the pipe for communication between the parent and child.
The parent process will write data to the pipe, and the child process will read data from the pipe.

Here’s a complete implementation:

c
Copy code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

#define BUFFER_SIZE 512

int main() {
int pipefd[2];
pid_t pid;
char write_msg[BUFFER_SIZE] = "Hello from parent process!";
char read_msg[BUFFER_SIZE];

// Create the pipe


if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}

// Fork the process


pid = fork();

if (pid < 0) {
perror("fork");
exit(EXIT_FAILURE);
}

if (pid > 0) { // Parent process


// Close the read end of the pipe
close(pipefd[0]);

// Write to the pipe


write(pipefd[1], write_msg, strlen(write_msg) + 1);

// Close the write end of the pipe


close(pipefd[1]);

// Wait for child process to finish


wait(NULL);
} else { // Child process
// Close the write end of the pipe
close(pipefd[1]);

// Read from the pipe


read(pipefd[0], read_msg, BUFFER_SIZE);

// Print the message


printf("Child process received message: %s\n", read_msg);
// Close the read end of the pipe
close(pipefd[0]);
}

return 0;
}

Explanation

1. Creating the Pipe:


o pipe(pipefd) creates an anonymous pipe. pipefd[0] is for reading, and
pipefd[1] is for writing.
2. Forking the Process:
o fork() creates a new process. The parent process will have a pid > 0, and the
child process will have a pid == 0.
3. Parent Process:
o The parent process closes the read end of the pipe using close(pipefd[0]).
o It writes a message to the pipe using write(pipefd[1], write_msg,
strlen(write_msg) + 1).
o After writing the message, it closes the write end of the pipe using
close(pipefd[1]).
o The parent process waits for the child process to finish using wait(NULL).
4. Child Process:
o The child process closes the write end of the pipe using close(pipefd[1]).
o It reads the message from the pipe using read(pipefd[0], read_msg,
BUFFER_SIZE).
o The received message is printed using printf.
o After reading the message, it closes the read end of the pipe using
close(pipefd[0]).

Compilation and Execution

To compile and run this program:

1. Save the code in a file, say pipe_example.c.


2. Open a terminal and navigate to the directory containing the file.
3. Compile the program using gcc:

bash
Copy code
gcc -o pipe_example pipe_example.c

4. Run the executable:

bash
Copy code
./pipe_example
You should see the message "Child process received message: Hello from parent process!"
printed by the child process.

You might also like