Você está na página 1de 20

Threads

CS 370
Spring-11

What is thread?
A single sequential flow of control within a program

Lightweight process?

Resouces are shared between the threads except the execution


context

Advantages
less time to create and destroy threads compared to processes

less time to switch between threads within the same process

less communication overhead

Disadvantage
Resources are shared!! Be Cautious!!

Implementing Threads
User Space

Kernel Space

Threads in User Space


Kernel doesn't know

Run on top of runtime system

Advantages
Even in those OS which don't support threads

Faster switching of threads

Each process can have its own scheduling algorithm

Scales better

Disadvantages
What if a thread has a blocking system call

Interruption needed! What if a thread doesn't voluntarily give up

Threads in Kernel Space


Creation and destruction of threads are done by kernel call

Advantages
No runtime system needed

when kernel blocks it may choose from same process or


different process

Disadvantages
Greater cost of creation and destruction of thread

Signal arrived! Which thread from the process to start?

Scheduler Activation
mimic the functionality of kernel threads but still have better
performance and greater flexibility as in user space

How?
Kernel assigns a number of virtual processors to each process.

Lets run time system allocate threads to processes.

Upcall
Kernel notifies the run-time system when a blocking call is
made.

Violation of structure in any layered system

Programming Project

Threads!

pthread_create

To create a new thread and start executing.

#include<pthread.h>

int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)
(void*), void *restrict arg);

*thread :

*attr :

*start_routine :

*arg :

Returns 0 on success, error number otherwise

A pointer to a thread id to store the id after its created.


A pointer to a thread attribute object, for our purposes use NULL
A function pointer to the function to be executed by the thread.

A pointer to the argument to be passed to the thread function.

pthread_join

This call will block until the specified thread has completed.

#include <pthread.h>

int pthread_join(pthread_t thread, void **value_ptr);

thead :

value_ptr:

Returns 0 on success, error number otherwise

id of the thread to wait for.


return value from the thread (pthread_exit())

pthread_exit

Used to end the threads execution and return a value (if needed) to the join function.

#include <pthread.h>

void pthread_exit(void *value_ptr);

*value_ptr:

pointer to the value that is to be returned to the join function.

Threads Example
#include <stdio.h>
#include <pthread.h>
int main() {
.
pthread_t threadIds[5]

for (i = 0; i < 5; i++) {


pthread_create(&threadIds[i], NULL, (void *)calledFxn, (void *)i);
}
for (i = 0; i < 5; i++) {
pthread_join(threadIds[i], NULL); // waiting for the threads
}

}
void calledFxn(void *arg) {
. //perform necessary tasks here
pthread_exit(NULL);
}

Race Condition

A race condition is an undesirable situation that occurs when a device or system attempts to
perform two or more operations at the same time, but because of the nature of the device or
system, the operations must be done in the proper sequence in order to be done correctly.

Race Condition Example

There are two threads (T1 and T2) that increment a global variable. Lets say these operations take
place:

Global integer = 0

T1 reads the value of the global integer (0)

T2 reads the value of the global integer (0)

T2 increments its stored value

T2 stores its value to the global integer (1)

T1 increments its stored value

T1 stores its value to the global integer (1)

Global integer value is 1

Both threads incremented the global integer by 1, so the result should be 2.

But from this example the global integer has the value 1

Critical Section

A piece of code that accesses a shared resource that must not be concurrently accessed by
more than one thread of execution.

We will use semaphores to create our critical sections.

sem_init

Used to initialize a semaphore.

#include <semaphore.h>

int sem_init(sem_t *sem, int pshared, unsigned int value);

*sem:

pshared :
used when sharing semaphores between processes, we will use 0 (not sharing
between processes)

Value:

pointer to the sem_t object to be initialized

initial value of the semaphore. Can be thought of how many open resources there

are. For critical section the value should be 1

Returns 0 on success, -1 on error

sem_wait

Used to enter the critical section.

#include <semaphore.h>

int sem_wait(sem_t *sem);

*sem:

Returns 0 on success, -1 on error

If the critical section is not available the call will block until it is available (another threads calls
sem_post).

pointer to the semaphore object to wait on.

sem_post

Used to notify that the thread is leaving the critical section.

#include <semaphore.h>

int sem_post(sem_t *sem);

*sem:

Returns 0 on success, -1 on error

pointer to the sem_t object to post to.

Semaphore Example..
#include <semaphore.h>
sem_t sem;
int main() {
..
sem_init(&sem, 0, 1); //initializing semaphore so that atmost one thread can be inside the critical section.
//create threads & call a function for threads to execute
.// join the threads
}
void callAfunction(void *threadArg) {
//

inside the called function


sem_wait(&sem); // waiting for the critical section
// do critical stuff here
sem_post(&sem); // releasing the control at the end of critical section
.//exit the threads

Você também pode gostar