Threads vs. Processes:
- A process is an independent execution unit with its own memory space, system resources, and a unique process ID (PID).
- A thread is a smaller unit of execution within a process. Multiple threads within the same process share the same memory space and system resources but have their own thread ID (TID).
Shared Process ID:
- All threads created within a single process share the same process ID because they belong to the same process. Threads don’t create new processes; they work within the boundaries of the parent process.
Table of Content
Table of Contents
Threads, Multi-Threading and Locks
Multithreading: Efficient Program Execution
- Allows multiple threads (small units of a process) to run within a single program
- Enables simultaneous task execution, improving efficiency
- Useful for handling multiple users or requests without running multiple copies of the program
- Threads share memory and data but maintain individual identities
Locks in Multithreading
- Purpose: Control access to shared resources (memory or data)
- Prevent errors caused by multiple threads accessing the same data simultaneously
- Basic concept:
- Lock before accessing shared data
- Unlock after accessing the data
- Other threads wait if a lock is already held
Basic Example of Multi-Threading
#include
#include
#include
#include
#include
// Global variable that is shared among threads
int g = 0;
// Thread function that will be executed by all threads
void* myThreadFun(void* vargp)
{
// Get the thread's process ID
int myid = getpid();
// Static variable shared among all threads
static int s = 0;
// Increment the static and global variables
++s;
++g;
// Print the thread's ID and the current values of static and global variables
printf("Process ID: %d, Static: %d, Global: %d\n", myid, ++s, ++g);
}
int main()
{
int i;
pthread_t tid;
// Create three threads that execute myThreadFun
for (i = 0; i < 3; i++)
pthread_create(&tid, NULL, myThreadFun, NULL);
// Wait for all threads to finish
pthread_exit(NULL);
return 0;
}
How it Works:
Global Variable (
g
):g
is a global variable that is shared by all threads. When any thread increments it, the updated value is visible to other threads.
Static Variable (
s
):s
is a static variable inside themyThreadFun
function. This means it is shared among all threads, but its scope is limited to the function. Since it’s static, its value persists between function calls. Each thread incrementss
, and the changes are reflected in every subsequent thread that accesses it.
Thread Creation:
- The program creates 3 threads using the
pthread_create()
function. Each thread runs themyThreadFun()
function. - The
pthread_exit()
inmain()
ensures that the program doesn’t exit before all threads have finished execution.
- The program creates 3 threads using the
Thread Execution:
- Each thread prints the process ID (obtained using
getpid()
), the incremented values of the static variables
, and the global variableg
. Even though the function is executed separately by each thread, the static and global variables are shared.
- Each thread prints the process ID (obtained using
Threaded Counter with Mutex Lock
Here’s an example where a mutex is used to protect shared data:
#include
#include
int counter = 0;
pthread_mutex_t lock;
void* thread_func(void* arg) {
pthread_mutex_lock(&lock);
counter++;
printf("Counter: %d\n", counter);
pthread_mutex_unlock(&lock);
return NULL;
}
int main() {
pthread_t t1, t2;
pthread_mutex_init(&lock, NULL);
pthread_create(&t1, NULL, thread_func, NULL);
pthread_create(&t2, NULL, thread_func, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_mutex_destroy(&lock);
return 0;
}
Explanation:
counter
: A shared variable that both threads will modify. Since multiple threads are accessing and modifying it, we need to protect it using a mutex.pthread_mutex_t lock
: A mutex (short for mutual exclusion) used to prevent concurrent access to thecounter
variable. This ensures that only one thread can modifycounter
at a time, avoiding race conditions.
void* thread_func(void* arg)
: This is the function that each thread will execute. In this case, it takes one argument (arg
), which is not used here (passed asNULL
when calling the function).pthread_mutex_lock(&lock)
: The thread acquires the mutex lock before modifying the sharedcounter
. This ensures that only one thread can increment the counter at a time.counter++
: The sharedcounter
variable is incremented.printf("Counter: %d\n", counter)
: The current value ofcounter
is printed.pthread_mutex_unlock(&lock)
: After modifying thecounter
, the thread releases the mutex lock, allowing other threads to acquire the lock and access the shared variable.return NULL
: Sincevoid*
is the return type, the function returnsNULL
(no data is returned by this function).
pthread_t t1, t2
: These are thread identifiers for two threadst1
andt2
.pthread_mutex_init(&lock, NULL)
: Initializes the mutexlock
. The second parameter is optional and can be set toNULL
for default mutex behavior.pthread_create(&t1, NULL, thread_func, NULL)
: This function creates a new threadt1
, which will start executing thethread_func
function.pthread_create(&t2, NULL, thread_func, NULL)
: Similarly, this creates a second threadt2
to executethread_func
.pthread_join(t1, NULL)
: Thepthread_join
function waits for threadt1
to finish executing. This ensures that the main thread does not exit beforet1
has completed its task.pthread_mutex_destroy(&lock)
: After all threads are done, the mutexlock
is destroyed to release any resources allocated for the mutex.
Output:
Counter: 1
Counter: 2
Practice Question:
Q1) Summing an Array Using Multiple Threads
Write a program that sums the elements of an array using multiple threads. Divide the array into equal parts, and assign each part to a separate thread. Each thread will sum the elements of its portion, and the main thread will collect and sum the results from each thread.
- Use a mutex lock to ensure that only one thread at a time updates the global sum.
- Example: If the array is
{1, 2, 3, 4, 5, 6}
, and you divide it between two threads, one thread will sum{1, 2, 3}
and the other will sum{4, 5, 6}
. Both results should be combined in the main thread to get the final sum.
Q2) Find Maximum Element in an Array Using Threads
Write a program that creates two threads to find the maximum element in two halves of an array. Then, determine the overall maximum from these results.
#include
#include
int arr[] = {1, 2, 3, 4, 5, 6};
int sum1 = 0, sum2 = 0;
void* sumFirstHalf(void* arg) {
for (int i = 0; i < 3; i++) sum1 += arr[i];
return NULL;
}
void* sumSecondHalf(void* arg) {
for (int i = 3; i < 6; i++) sum2 += arr[i];
return NULL;
}
int main() {
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, sumFirstHalf, NULL);
pthread_create(&thread2, NULL, sumSecondHalf, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
int totalSum = sum1 + sum2;
printf("Total Sum: %d\n", totalSum);
return 0;
}
#include
#include
int arr[] = {10, 20, 5, 30, 25, 15};
int max1 = 0, max2 = 0;
void* findMaxFirstHalf(void* arg) {
for (int i = 0; i < 3; i++) {
if (arr[i] > max1) max1 = arr[i];
}
return NULL;
}
void* findMaxSecondHalf(void* arg) {
for (int i = 3; i < 6; i++) {
if (arr[i] > max2) max2 = arr[i];
}
return NULL;
}
int main() {
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, findMaxFirstHalf, NULL);
pthread_create(&thread2, NULL, findMaxSecondHalf, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
int overallMax = (max1 > max2) ? max1 : max2;
printf("Maximum Element: %d\n", overallMax);
return 0;
}
Recent Comments
Categories
- Angular
- AWS
- Backend Development
- Big Data
- Cloud
- Database
- Deployment
- DevOps
- Docker
- Frontend Development
- GitHub
- Google Cloud Platform
- Installations
- Java
- JavaScript
- Linux
- MySQL
- Networking
- NodeJS
- Operating System
- Python
- Python Flask
- Report
- Security
- Server
- SpringBoot
- Subdomain
- TypeScript
- Uncategorized
- VSCode
- Webhosting
- WordPress
Search
Recent Post
Understanding Mutex, Semaphores, and the Producer-Consumer Problem
- 13 October, 2024
- 10 min read
Process scheduling algorithm – FIFO SJF RR
- 14 September, 2024
- 8 min read
How to Implement Multithreading in C Language
- 8 September, 2024
- 9 min read
Featured Videos
All Tags
Angular
API
AWS
Bash
Bash Scripting
Big Data
C Language
Cloud Server
Cluster
Command Line
CRUD
Database
Deployment
DevOps
Docker
Elementor
GitHub
Google Cloud
Google Cloud Platform
HBase Database
Header
installation
JasperReport
Java
JavaScript
Linux
Local Server
MySQL
NodeJS
npm
Programming
Publish
Puppeteer
Python
S3 Bucket
Security
SpringBoot
SSH
Terminal
ternary operators
TypeScript
Virtual Machines
Webhosting
Windows
WordPress