==============================================================
  Experiment 08: Multithreaded Mean, Median & Standard Deviation
==============================================================
  [Back to Index]
--------------------------------------------------------------

AIM:
  To write a multithreaded program that calculates the mean,
  median, and standard deviation for a list of integers using
  three separate worker threads.

--------------------------------------------------------------

THEORY:
  Multithreading allows a program to execute multiple threads
  concurrently within the same process. Threads share the same
  memory space and can perform different tasks simultaneously.

  In this program:
    Thread 1 calculates the mean
    Thread 2 calculates the median
    Thread 3 calculates the standard deviation

  The computed values are stored in global variables. The parent
  thread waits for all worker threads to finish using
  pthread_join() and then displays the results.

--------------------------------------------------------------

FORMULAE USED:
  Mean   = Sum(x) / n
  Median = Middle value of sorted data
  StdDev = sqrt( Sum((x - mean)^2) / n )

--------------------------------------------------------------

ALGORITHM:
  1. Start the program.
  2. Read integers from command-line arguments.
  3. Store integers in an array.
  4. Create three threads:
     - Mean thread
     - Median thread
     - Standard deviation thread
  5. Mean thread computes average value.
  6. Median thread sorts the array and computes median.
  7. Standard deviation thread computes standard deviation.
  8. Parent thread waits for all threads using pthread_join().
  9. Display mean, median, and standard deviation.
  10. Stop the program.

--------------------------------------------------------------

SOURCE CODE: multithread_stats.c

--------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>

double mean, median, stddev;

int *arr;
int n;

// Thread function for Mean
void *calculate_mean(void *arg) {

    int sum = 0;

    for (int i = 0; i < n; i++) {
        sum += arr[i];
    }

    mean = (double)sum / n;

    pthread_exit(0);
}

// Thread function for Median
void *calculate_median(void *arg) {

    // Sort array
    for (int i = 0; i < n - 1; i++) {
        for (int j = i + 1; j < n; j++) {

            if (arr[i] > arr[j]) {
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
    }

    if (n % 2 == 0)
        median = (arr[n/2] + arr[(n/2)-1]) / 2.0;
    else
        median = arr[n/2];

    pthread_exit(0);
}

// Thread function for Standard Deviation
void *calculate_stddev(void *arg) {

    double variance = 0.0;

    for (int i = 0; i < n; i++) {
        variance += (arr[i] - mean) * (arr[i] - mean);
    }

    variance = variance / n;

    stddev = sqrt(variance);

    pthread_exit(0);
}

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

    if (argc < 2) {
        printf("Usage: ./multithread_stats numbers...\n");
        return 1;
    }

    n = argc - 1;

    arr = (int *)malloc(n * sizeof(int));

    for (int i = 0; i < n; i++) {
        arr[i] = atoi(argv[i + 1]);
    }

    pthread_t tid1, tid2, tid3;

    // Create threads
    pthread_create(&tid1, NULL, calculate_mean, NULL);
    pthread_join(tid1, NULL);

    pthread_create(&tid2, NULL, calculate_median, NULL);
    pthread_create(&tid3, NULL, calculate_stddev, NULL);

    pthread_join(tid2, NULL);
    pthread_join(tid3, NULL);

    printf("Mean = %.2lf\n", mean);
    printf("Median = %.2lf\n", median);
    printf("Standard Deviation = %.2lf\n", stddev);

    free(arr);

    return 0;
}
--------------------------------------------------------------

COMPILE: gcc -o multithread_stats multithread_stats.c -lpthread -lm
RUN:     ./multithread_stats 90 81 56 55 40 35 20 15 10 4

--------------------------------------------------------------

FUNCTIONS USED:
  pthread_create() - Creates thread
  pthread_join()   - Waits for thread completion
  sqrt()           - Calculates square root
  atoi()           - Converts string to integer

--------------------------------------------------------------

THEORY OF THREADS IN OPERATING SYSTEMS:

  A thread is the smallest unit of execution within a process.
  A process can contain multiple threads that execute concurrently
  while sharing the same memory space, code section, and resources.

  Threads are also called lightweight processes because they
  require fewer resources than full processes.

  Multithreading allows a program to perform multiple tasks
  simultaneously, improving CPU utilization and performance.

--------------------------------------------------------------

PROCESS vs THREAD:

  Process                     | Thread
  ----------------------------|----------------------------------
  Independent execution unit  | Part of a process
  Has separate memory space   | Shares memory with other threads
  Creation is slower          | Creation is faster
  Communication is expensive  | Communication is easier
  Heavyweight                 | Lightweight

--------------------------------------------------------------

FEATURES OF THREADS:

  Threads share:
    - Code section
    - Data section
    - Heap memory
    - Open files

  Each thread has its own:
    - Program counter
    - Registers
    - Stack

--------------------------------------------------------------

TYPES OF THREADS:

  1. User-Level Threads
     - Managed by user-level libraries
     - Kernel is unaware of these threads
     - Faster thread management
     - Example: POSIX Threads (Pthreads)

  2. Kernel-Level Threads
     - Managed directly by the OS kernel
     - Kernel schedules the threads
     - More overhead than user-level threads

--------------------------------------------------------------

THREAD OPERATIONS IN PTHREADS:

  pthread_create() - Creates a new thread
  pthread_join()   - Waits for a thread to finish
  pthread_exit()   - Terminates a thread

--------------------------------------------------------------

ADVANTAGES OF THREADS:
  1. Faster execution
  2. Better CPU utilization
  3. Efficient resource sharing
  4. Improved responsiveness
  5. Easier communication between threads

DISADVANTAGES OF THREADS:
  1. Synchronization problems
  2. Race conditions
  3. Difficult debugging
  4. Deadlocks may occur

==============================================================
  [Prev: Exp 07]  |  [Next: Exp 09]
==============================================================