Threads Flashcards
Describe a thread?
A thread is a sequence of instructions that are executed by a process. it is a lightweight program.
Each thread that belongs to a process space has a separate stack and registers but they all share the same vritual address space.
So they share the same code, data and and open files
Why are multiple threads needed?
Because applications do more than one thing at a time.
Multithreading allows us to not have to program the interleaved execution ourselves
We do not have to wait for one task to complete (like IO operations) before doing another task
What flag do you use to link the thread library to the user code.
Use the “-pthread” flag
What is the data type of
- thread ID:
- thread attr:
- thread start routine:
- thread ID: pthread_t – unsigned long
- thread attr: pthread_attr_t
- thread start routine: void* (*start_routine) (void*)
What is the prototype of pthread create, what does it return?
int pthread_create(
- pthread_t* restrict threadid,
- pthread_attr* restrict threadattr,
- void* ( *start_routine ) ( void* ),
- void* restrict arg
)
the restrict keyword is used to make sure that the pointers do not point to any of the same memory locations.
Success: returns 0
Failure: returns an error number
In which 3 cases does a thread terminate?
A thread terminates on one of the 3 cases.
- The start routine function ends
- The thread calls the pthread_exit function
- The program terminates ( main function terminates )
What is the prototype for pthread_exit()
void pthread_exit(void* )
What function is used to get the id of the current thread:
Use the pthread_self( ) function to get id of the current thread.
What is a thread safe function
A thread safe function is a function that executes correctly even when it is executed simultaneously by multiple threads.
What are re-entrant functions?
These are thread safe functions, they usually have _r at the end.
Prototype of the pthread_join
void pthread_join(pthread_t threadid, void ** ptr)
threadid: id of the thread that is to be joined.
ptr: the pointer to where the return value of the thread is stored.
What is thread cancellation and what is the function that can be used for this?
One thread can request the cancellation of another thread.
int pthread_cancel( pthread_t thread)
On success this returns 0 or otherwise it just returns an error value
What are the 3 ways in which multithreaded programs can go wrong?
The three ways are:
- Race conditions
- Thread starvation
- Deadlock
What are race conditions?
What are critical sections?
Simultaneuous access of 2 threads lead to data being stored to be inconsistent
Critical sections are those points in the code that can lead to data race conditions
Give an example for race condition.
Incrementing of a variable int i = 1
i++;
First thread sees i = 1
Second thread sees i = 1 before the first thread can increment it and write it back
First thread increments i to 2 and writes it back to the memory location of i
Second thread also increments its copy of i ( which was 1 ) to 2 and writes it back
The final value of i is 2, when actually it should’ve been 3.
What are mutexes and what do they ensure?
Mutexes are variables that can be locked on by threads.
They provide mutual exclusion or non interference between threads that execute the same code.
How do you create a mutex?
You create mutex using the pthread_mutex_init function
int pthread_mutex_init( pthread_mutex_t* mutex, const pthread_mutexattr_t* attr );
How do you create mutexes for global variables?
You use the static mutex initialazer
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER
How do you destroy a mutex?
Why is it important to destroy a mutex once you are done using it?
You use the pthead_mutex_destroy function and this taken in the pointer to the mutex
pthread_mutex_destroy( pthread_mutex_t* mutex );
You must destroy a mutex because the pthread library does not clean up for you.
When can the usage of mutexes lead to undefined behaviour
The usage of mutexes can lead to undefined behaviour when:
- trying to lock a mutex that has not been initialized
- trying to unlock a mutex that has not been locked
- trying lock a mutex twice
- trying to lock a mutex that has been locked by another thread
What is trylock and what does it return?
Trylock is used when you want a thread to attempt to lock on a mutex but not wait wait on the mutex if it is unavailable.
It returns:
- 0, if it is successful
- EBUSY if it was unsuccessful
- EINVAL if the mutex is invalid
What is deadlock?
Deadlock is when 2 threads that are executing are waiting on each other’s resources.
So if 2 threads A and B are executing and if A is waiting for B’s resources while B is waiting for A’s resources, then the neither of the threads can continue their execution and this condition is called a deadlock.
What do you have to keep in mind when you’re working with multiple locks inorder to avoid deadlocks?
When you’re working with mutliple locks, you would need to make sure that you lock the mutexes in the same order in the different threads.
Why is it advantageous to hold mutexes for as short as possible?
When you minimize the time the time that you spend holding onto mutexes, then
- there is less chance that there are mutex related mistakes, like relocking or forgetting to unlock
- it makes the code more parallel as more number of threads are allowed into the code block.