Select Page

Use separate threads to switch on different LED’s with speed Control from console and keystrokes.

ABSTRACT

The main aim of the experiment is to get familiarized with using threads and create multi threaded application to control the switch on and off of the LED ’s by calling syscall functions created in the last lab in different threads. Apart from the three threads created for different colors two new threads are also added first for console application which takes the user input in microseconds and adjusts the blinking
speed accordingly. The second thread takes user input in form of key strokes and either doubles the blinking speed or halves it depending upon the key pressed. Key ’i’ is used for doubling the blinking speed and ’d’ is used for halving it. The user code makes the system call using the threads for different colors as well as for the console and the Keystrokes.

I   INTRODUCTION

A thread is a path which the program follows during its execution. Most of the programs written are single threaded i.e they perform a particular task and will be unresponsive till that task is finished. As an example a single threaded application will wait for the user input from the console before taking user input from the keys. A multithreaded program can perform different tasks at the same time without blocking one another. Multithreaded application work more efficiently by sharing resources and have improved performance. Applications like web browsers games and many other program make use of Multithreading and they are also an integral part of the Operating System. Its important to distinguish process and threads, while process is a program being executed which is further divide into independent units called threads. Therefore a thread is like a small weight process within a process., or in other sense a process is collection of threads. So thread is a schedulable light weight process in some sense. A thread has following life cycle
1. New: A new thread is born
2. Runnable: Athread becomes runnable after it starts
3.Waiting: While waiting for another thread to perform a task the current running can go to the waiting state until it does not recieve signal from the other thread.
4. Timed Waiting: A runnable thread enters into this state for a specific time interval and then transitions back when the time interval expires.
5. Dead: A thread enters this state after completing the task.

II   IMPLEMENTATION

2.1Calling all libraries:

#include <stdio.h>     // standard library functions like printf and scanf
#include <unistd.h>   // Access to POSIX standard API, including usleep
#include <sys/syscall.h>   // provides access to syscall interface
#include <pthread.h>      //include the POSIX thread library
#include <stdlib.h>        //libraries for general utilities
#include <termios.h>    //provides terminal control functions and manipulate terminal
function
#define  SYS_LED_toggle 454    // Adjust according to your system call number
#define  MIN_BLINK_SPEED 1000   // Minimum blink speed in microseconds(macros
definition)
int  blink_speed = 1000000;    // Initial blink speed (1 second) by default
pthread_mutex_t speed_lock;    // Mutex for thread-safe access to blink_speed
The global variable blink speed is used to update the blink speed for all the LED’s. speed lock Mutex is used to perform thread-safe operations.

2.2 LED Control thread Function:

void* led_control(void* arg) {
int color = *(int*)arg;    // Color of the LED (0 = Red, 1 = Yellow, 2 = Green)
while (1) {
syscall(SYS_LED_toggle, color, 1);    // Turn the LED on
pthread_mutex_lock(&speed_lock);
int current_speed = blink_speed;     // Read the current blink speed 
pthread_mutex_unlock(&speed_lock);
usleep(current_speed);      // Sleep based on blink speed
syscall(SYS_LED_toggle, color, 0);     // Turn the LED off
pthread_mutex_lock(&speed_lock);
current_speed = blink_speed;      // Read the current blink speed again
pthread_mutex_unlock(&speed_lock);
usleep(current_speed);      
}
return NULL; }

This function is executed by the led control threads and it toggles LED ON and OFF. The current blink speed is also read by reading the value of blink speed, color specifies the specific of which LED to control 0 turns it off and 1 turns it on pthread mutex lock(&speed lock) and pthread mutex unlock(&speed lock) locks and unlock the mutex to safely access blink speed variable.The usleep() function then sleeps the system for current speed.

2.3    User input thread function:

void* user_input_thread(void* arg) {
while (1) {
int new_speed;
set_echo_and_canonical_mode(1);
printf(“Enter new blink speed in microseconds (minimum %d): “,
MIN_BLINK_SPEED);
scanf(“%d”, &new_speed);
pthread_mutex_lock(&speed_lock);
if (new_speed >= MIN_BLINK_SPEED) {
blink_speed = new_speed;
printf(“Blink speed updated to %d microseconds.\n”, new_speed);
} else {
printf(“Blink speed must be at least %d microseconds. Ignoring input.\n”,
MIN_BLINK_SPEED);
}
pthread_mutex_unlock(&speed_lock);
}
return NULL;
}
This function is executed by the user input thread. it takes input from the user to update the blink speed. Then set the console for the user using set echo and canonical mode(). scanf() Reads an integer input from the user.

2.4   Key input thread function:

void* key_input_thread(void* arg) {
while (1) {
printf(“Press ’i’ to double speed, ’d’ to halve speed.\n”);
int ch;
set_echo_and_canonical_mode(1);    // Enable echo for key input
ch = getchar();    // Get the character input

pthread_mutex_lock(&speed_lock);
if (ch == ’i’) {      // ’i’ key (double the speed)
blink_speed = blink_speed / 2;    // Double the speed (halve the duration)
if (blink_speed < MIN_BLINK_SPEED)
{   blink_speed = MIN_BLINK_SPEED;     // Ensure blink_speed doesn’t fall
below the minimum
}
printf(“Blink speed increased to %d microseconds.\n”, blink_speed);
} else if (ch == ’d’) {      // ’d’ key (halve the speed)
blink_speed = blink_speed * 2;     // Halve the speed (double the duration)
printf(“Blink speed decreased to %d microseconds.\n”, blink_speed);
}
pthread_mutex_unlock(&speed_lock);
}
return NULL;

}

This function is executed by the key input thread. It adjusts the blink speed based on key presses ( ’i’ and ’d’). getchar() reads a single character from the standard input and is checked against stored value.

2.5   Main function

int main() {
pthread_t red_thread, yellow_thread, green_thread, user_thread, key_thread;
int red = 0, yellow = 1, green = 2;
pthread_mutex_init(&speed_lock, NULL);      // Initialize the mutex
// Create threads for each LED color
pthread_create(&red_thread, NULL, led_control, &red);
pthread_create(&yellow_thread, NULL, led_control, &yellow);
pthread_create(&green_thread, NULL, led_control, &green);
// Create a thread for user input to update the blink speed
pthread_create(&user_thread, NULL, user_input_thread, NULL);
// Create a thread for ’i’ and ’d’ key input to modify the blink speed
pthread_create(&key_thread, NULL, key_input_thread, NULL);
// Wait for threads to finish (they won’t in this case, so this is just to keep
main alive)
pthread_join(red_thread, NULL);
pthread_join(yellow_thread, NULL);
pthread_join(green_thread, NULL);
pthread_join(user_thread, NULL);
pthread_join(key_thread, NULL);
pthread_mutex_destroy(&speed_lock);    // Clean up the mutex
return 0;
}
Here threads are executed in parallel and are later joined since they never return any value infinite loop. pthread mutex init(&speed lock, NULL) intializes the mutex. pthread create(&thread, NULL, function, &arg). Creates a new thread that executes function with arg as its argument. pthread join(thread,NULL) waits for the specified thread to terminate pthread mutex destroy(&speed lock) destroys the mutex after use.Here it is ensured that the user input and key presses are managed independently.

III   CONCLUSION

A Multithreaded application to run LED’s in parallel was created and tested. The LED’s were found to glow parallely and synchronously with the same speed as blink speed specified by the user either through console or through key press ’i’ or ’d’. the following command will list all the process with number of threads running.

$ ps -e -o pid,cmd,nlwp

The output will be seen as in figure 1.

Figure 1: Showing number of threads

 

The output of htop command also gives the same. This is shown in the figure2.

Figure 2: All threads of the LED thread example