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

Understanding Processes and Threads

Chapter 4 discusses the differences between processes and threads, highlighting that processes are independent with separate resources, while threads are lightweight units within a process that share memory. It includes examples of thread creation using the POSIX <pthread.h> API in C, demonstrating how to pass data to threads and manage their execution. Additionally, it covers the implications of using global versus local variables in multithreaded environments.

Uploaded by

Mohamed adel
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)
7 views16 pages

Understanding Processes and Threads

Chapter 4 discusses the differences between processes and threads, highlighting that processes are independent with separate resources, while threads are lightweight units within a process that share memory. It includes examples of thread creation using the POSIX <pthread.h> API in C, demonstrating how to pass data to threads and manage their execution. Additionally, it covers the implications of using global versus local variables in multithreaded environments.

Uploaded by

Mohamed adel
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

Chapter 4 Exercises

Remember Process vs Threads


● A child process is a separate, independent
process created by a parent. It has its own
Process ID (PID), PCB, and resources, and it’s
placed in the process queue. If the parent
process terminates, the child process may or may
not be affected.

● A thread, on the other hand, is a smaller unit


within a process that shares the same memory and
resources. If the parent process dies, all its
threads die as well.
Remember Process vs Threads

Analogy:
● A process is like a house — it has its own
foundation, wiring, and address. Different houses
can only communicate through formal methods (like
IPC).

● A thread is like a room within the same house —


it shares everything (plumbing, wiring, and
address) with other rooms. Communication is easy,
but if the house collapses, all rooms are lost
too.
Threads

● Threads are lightweight units of execution within a process.

● They allow a program to perform multiple tasks


concurrently, improving efficiency and responsiveness.

● 💡 Example: Just like you can listen to music while writing


code, threads let your program do several things at once.
Process Thread
Definition An independent program in A segment (or lightweight unit) of a
execution process

Weight Heavyweight Lightweight

Creation Time more time less time

Termination Time more time less time

Communication Slower and requires inter-process Faster as they share the same
communication (IPC) mechanisms memory space

Context Switching Slower Faster

Resource Usage More resources (separate memory Fewer resources


and system resources)

Scheduling by OS Each process is treated as a All the level peer threads are
separate task by the OS treated as a single task by OS

Memory Sharing have separate memory spaces Share the same memory and
resources (like data and code)

Dependency Independent of each other Dependent on their parent process.


Process vs Thread

Process: A complete program in execution with its own


memory space

Thread: A subset of a process that shares the same


memory space with other threads

Difference: Multiple threads = shared resources,


Multiple processes = isolated resources
Process vs Thread
Thread

● Has its own stack.


● Did not create a copy of the PCB
in memory.
● Data access is within the same
process itself.

Process

● A copy of the program itself executes.


● The new process can not modify data
stored in the parent process.
Process vs Thread in Memory
<pthread.h>

● In C language, POSIX <pthread.h> standard API


(Application program Interface) for all thread related
functions.

● It allows us to create multiple threads for concurrent


process flows.
<pthread.h>

Function Description Usage Return Value

pthread_create() Creates a new thread int pthread_create( pthread_t *thread, const


and starts execution. pthread_attr_t *attr, void*(*start_routine)(void *),
void *arg);
Takes a function pointer
● thread: The ID of the thread to wait for. This must be a
that will be executed in thread created by pthread_create().
the new thread.
● attr: Pointer to a thread attributes object that sets options
like stack size, scheduling policy, etc. You can pass NULL to Return Value
use default attributes.
● Returns 0 on success.
● start_routine: Pointer to the function that the thread will
execute. This function must take a single void * argument
● Returns a nonzero
and return a void * result.
error code (e.g.,
● arg: A pointer to the argument you want to pass to the EINVAL, EAGAIN) on
thread function. Use NULL if no argument is needed. failure.

pthread_join() Waits for the specified pthread_join(pthread_t thread, void **retval);


thread to terminate. It
● thread: The ID of the thread to wait for. This must be a
blocks the calling thread thread created by pthread_create().
until the target thread
finishes. ● retval: A pointer to a pointer that will store the value
returned by the thread’s start function (return value). If
you don’t care about the return value, pass NULL.
4.1 Pthread_create
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

// Function that will be executed by the thread generic pointer type — a special kind
of pointer that can hold the address of
any data type.
void* print_message(void* msg) {
char *string = (char*) msg;
printf("%s\n", string);
return NULL;
} data type defined in the POSIX
int main() { Threads (pthreads) library, used to
uniquely identify a thread.

pthread_t thread1, thread2; // Declare two thread identifiers


const char* message1 = "Hello from thread 1!";
const char* message2 = "Hello from thread 2!";

// Create two threads


pthread_create(&thread1, NULL, print_message, message1);
pthread_create(&thread2, NULL, print_message, message2);

// Wait for the threads to finish


pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("Hello from the Main Thread\n") ;
return 0;
}
4.2 Passing Struct data to a thread
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Define a struct to hold data


typedef struct {
int id;
char message[50];
} thread_data_t;

void *thread_function(void *arg) {


thread_data_t *data = (thread_data_t *)arg;
printf("Thread ID: %d, Message: %s\n", data->id, data->message);
return NULL;
}

int main() {
pthread_t thread;
thread_data_t data = {1,"Hello from the thread!"} ;
pthread_create(&thread, NULL, thread_function, (void *)&data) ;
pthread_join(thread, NULL);
return 0;
}
4.3 Passing Pointer to a local variable
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void *thread_function(void *arg) {
int *id = (int *)arg;
printf("Thread received ID: %d\n", *id);
return NULL;
}
Wrong Output!!!
int main() {
pthread_t threads[10];

for (int i = 0; i < 10; i++) {


int data = i; // Local variable reused for each thread
pthread_create(&threads[i], NULL, thread_function, &data) ;
}
for (int i = 0; i < 10; i++) {
pthread_join(threads[i], NULL);
}

return 0;
}
4.3 Passing Pointer to a local variable
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

void *thread_function(void *arg) {


int *id = (int *)arg;
printf("Thread received ID: %d\n", *id);
free(id) ; // free allocated memory
return NULL;
Correct Version
}

int main() {
pthread_t threads[10];

for (int i = 0; i < 10; i++) {


int *data = malloc(sizeof(int));// allocate memory for ID
*data = i;
pthread_create(&threads[i], NULL, thread_function, data) ;
}
for (int i = 0; i < 10; i++) {
pthread_join(threads[i], NULL);
}

return 0;
}
4.4 Return Value from Thread
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h> // Thread function to sum a segment of prime
#define NUM_THREADS 2 numbers
int primes[10] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29}; void* thread_function(void* arg) {
thread_data_t* data = (thread_data_t*)arg;
typedef struct { // Cast the argument to the correct type
int start_index; int start = data->start_index;
int count; int count = data->count;
} thread_data_t; int sum = 0;
for (int i = 0; i < count; i++) {
int main() { sum += primes[start + i];
pthread_t threads[NUM_THREADS]; }
thread_data_t thread_data[NUM_THREADS]; // dynamic allocation for the answer and
int i; return the pointer to the main_thread
int *result ; int* result = malloc(sizeof(int));
int global_sum = 0; *result = sum;
// Create threads to sum segments of the prime array // If we returned a pointer to a local
for (i = 0; i < NUM_THREADS; i++) { variable
thread_data[i].start_index = i * 5; // Starting index for each thread (0 and 5) // int *result = &sum ;
thread_data[i].count = 5; // Each thread sums 5 numbers return result;
pthread_create(&threads[i], NULL, thread_function,&thread_data[i]); }
}
for (i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], (void**)&result);
global_sum += *result;
free(result); // Free the allocated memory for the result
}
printf("Global Sum is %d\n", global_sum);
return 0;
}
4.5 Global vs. Local Variables in Threads
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int global_counter = 0; // Global variable shared by all threads


void *thread_function(void *arg) {
int local_counter = 0; // Local variable unique to each thread
int * data = (int*) arg ;
global_counter++;
local_counter++;
printf("Thread %d - Global: %d, Local: %d\n", *data, global_counter, local_counter); // What is the output of this line
free(data);
return NULL;
}

int main() {
pthread_t threads[2];
for (int i = 0; i < 2; i++) {
int* data = malloc(sizeof(int));
*data = i;
pthread_create(&threads[i], NULL, thread_function, data);
}
for (int i = 0; i < 2; i++) {
pthread_join(threads[i], NULL);
}
printf("Final Global Counter: %d\n", global_counter); // What is the output of this line
return 0;
}

You might also like