CENG 360 Operating systems and system programming Lecture

  • Slides: 26
Download presentation
CENG 360 - Operating systems and system programming Lecture 16 threads (Linux)

CENG 360 - Operating systems and system programming Lecture 16 threads (Linux)

Thread definition • A thread is a basic unit of CPU utilization within a

Thread definition • A thread is a basic unit of CPU utilization within a process • Each thread has its own – – thread ID program counter register set stack • It shares the following with other threads within the same process – – code section data section the heap (dynamically allocated memory) open files • A multi-threaded process can do multiple things at once • A thread remains attached to his process

Thread definition – Graphical view

Thread definition – Graphical view

Advantage of Threads • Economy: – Creating a thread is cheap • Much cheaper

Advantage of Threads • Economy: – Creating a thread is cheap • Much cheaper than creating a process – Context-switching between threads is cheap • Much cheaper than between processes • Resource Sharing: – Threads naturally share memory • With processes we have to use complicated IPC – Having concurrent activities in the same address space is very powerful

Disadvantage of Threads • If one thread fails, then the process fails. – Not

Disadvantage of Threads • If one thread fails, then the process fails. – Not the case with processes • Threads are more memory-constrained than processes – Due to OS limitation of the address space size of a single process

Threads on my Linux • Use man to understand the following commands top (like

Threads on my Linux • Use man to understand the following commands top (like task manager in Windows) ps (list processes) Use ps –u. M to see processes with the associated threads.

Multi-threading challenge • Typical challenges of multi-threaded programming – Dividing activities among threads –

Multi-threading challenge • Typical challenges of multi-threaded programming – Dividing activities among threads – Balancing load among threads – Split data among threads – Deal with data dependency and synchronization – Testing and Debugging

Threads • Threads can be supported in: • User Space – The Kernel knows

Threads • Threads can be supported in: • User Space – The Kernel knows nothing of the existence of multiple threads – Threads are managed by some user-level thread library • Ex: Java Green Threads • Kernel Space – The kernel has data structure and functionality to deal with threads – Most modern OS support kernel threads

Kernel thread support • Different models can be used to support threading in kernel

Kernel thread support • Different models can be used to support threading in kernel mode: – – Many to one model One to one model Many to many model Two level model We are talking here about the relation between the OS and the threads.

Kernel thread support • Many to one • Advantage: multi-threading is efficient and low-overhead

Kernel thread support • Many to one • Advantage: multi-threading is efficient and low-overhead – No syscall to the kernel • Major Drawback : if one threads blocks, then do all the others!

Kernel thread support • One to one • Removes drawback of the Many-to-One Model

Kernel thread support • One to one • Removes drawback of the Many-to-One Model • Creating a new threads requires work by the kernel – Not as fast as in the Many-to-One Model • Example: – Linux – Windows

Kernel thread support • Two level • Uses both one to one and many

Kernel thread support • Two level • Uses both one to one and many to many • The user choose • Example: – IRIX, HP-UX, Tru 64 UNIX – Solaris 8 and earlier

Thread Libraries • Thread libraries provide users with ways to create threads in their

Thread Libraries • Thread libraries provide users with ways to create threads in their own programs – In C/C++: Pthreads • Implemented by the kernel – In Java: Java Threads • Implemented by the JVM, which relies on threads implemented by the kernel We will talk only about Pthreads

Pthread: POSIX Thread • Pthreads is a standard set of C library functions for

Pthread: POSIX Thread • Pthreads is a standard set of C library functions for multithreaded programming – IEEE Portable Operating System Interface, POSIX, section 1003. 1 standard, 1995 • Pthread Library (60+ functions) – Thread management: create, exit, detach, join, . . . – Tools for synchronization, . . . • Programs must include the file pthread. h • Programs must be linked with the pthread library (-lpthread) gcc -lpthread test. o –o test

Pthread: Creation pthread_create() • Creates a new thread Return 0 for success otherwise an

Pthread: Creation pthread_create() • Creates a new thread Return 0 for success otherwise an error code int pthread_create ( output argument for the pthread_t *thread, id of the new thread pthread_attr_t *attr, void * (*start_routine) (void *), void *arg); input argument that specifies the attributes of the thread to be created (NULL = default attributes) argument to pass to the new thread routine. If the thread routine requires multiple arguments, they must be passed bundled up in an array or a structure

Pthread: Creation pthread_create() • Creates a new thread int pthread_create ( pthread_t *thread, pthread_attr_t

Pthread: Creation pthread_create() • Creates a new thread int pthread_create ( pthread_t *thread, pthread_attr_t *attr, void * (*start_routine) (void *), void *arg); start_routine: function to use as the start of the new thread

Pthread: Example Objective: Create a thread to compute the sum of the elements of

Pthread: Example Objective: Create a thread to compute the sum of the elements of an array. Step by step design… • Needs three arguments – the array – its size – where to store the sum typdef struct { int array[5]; int size; int sum; } arguments;

#include <pthread. h> Pthread: Example #include <stdio. h> #include <stdlib. h> int main ()

#include <pthread. h> Pthread: Example #include <stdio. h> #include <stdlib. h> int main () typedef struct { { int array[5]; pthread_t wt; int size; arguments arg; int sum; int i; } arguments; for (i=0; i<5; i++) void *compute(void *arg) arg. array[i] = i; { arg. size = 5; int i; pthread_create(&wt, NULL, arguments *str=(arguments *)arg; compute, &arg); str->sum=0; return 0; for (i = 0; i < str->size; i++) } str->sum += str->array[i]; printf (" The sum is : %d n", str->sum); return; }

#include <pthread. h> Challenging questions 1 #include <stdio. h> #include <stdlib. h> int main

#include <pthread. h> Challenging questions 1 #include <stdio. h> #include <stdlib. h> int main () typedef struct { { int array[5]; pthread_t wt; int size; arguments arg; int sum; int i; } arguments; for (i=0; i<5; i++) void *compute(void *arg) arg. array[i] = i; { arg. size = 5; int i; pthread_create(&wt, NULL, arguments *str=(arguments *)arg; compute, &arg); str->sum=0; return 0; for (i = 0; i < str->size; i++) } str->sum += str->array[i]; printf (" The sum is : %d n", str->sum); What will ps –u. M show after while(1); running this program? Why? return; }

#include <pthread. h> Challenging questions 2 #include <stdio. h> #include <stdlib. h> int main

#include <pthread. h> Challenging questions 2 #include <stdio. h> #include <stdlib. h> int main () typedef struct { { int array[5]; pthread_t wt; int size; arguments arg; int sum; int i; } arguments; for (i=0; i<5; i++) void *compute(void *arg) arg. array[i] = i; { arg. size = 5; int i; pthread_create(&wt, NULL, arguments *str=(arguments *)arg; compute, &arg); str->sum=0; while(1); for (i = 0; i < str->size; i++) return 0; str->sum += str->array[i]; printf (" The sum is : %d n", str->sum); } while(1); } return; What about now?

#include <pthread. h> #include <stdio. h> #include <stdlib. h> typedef struct { int array[5];

#include <pthread. h> #include <stdio. h> #include <stdlib. h> typedef struct { int array[5]; int size; int sum; } arguments; void *compute(void *arg) { int i; arguments *str=(arguments *)arg; str->sum=0; for (i = 0; i < str->size; i++) str->sum += str->array[i]; printf (" The sum is : %d n", str->sum); return; } Challenging questions 3 int main () { pthread_t wt; arguments arg; int i; for (i=0; i<5; i++) arg. array[i] = i; arg. size = 5; pthread_create(&wt, NULL, compute, &arg); printf(“SUM= %d n”, arg. sum); return 0; } What will be printed?

#include <pthread. h> #include <stdio. h> #include <stdlib. h> typedef struct { int array[5];

#include <pthread. h> #include <stdio. h> #include <stdlib. h> typedef struct { int array[5]; int size; int sum; } arguments; void *compute(void *arg) { int i; arguments *str=(arguments *)arg; str->sum=0; sleep(1); for (i = 0; i < str->size; i++) str->sum += str->array[i]; printf (" The sum is : %d n", str->sum); return; } Challenging questions 4 int main () { pthread_t wt; arguments arg; int i; for (i=0; i<5; i++) arg. array[i] = i; arg. size = 5; pthread_create(&wt, NULL, compute, &arg); printf(“SUM= %d n”, arg. sum); return 0; } What will be printed now?

Understanding the example • The main thread continues its normal execution after creating the

Understanding the example • The main thread continues its normal execution after creating the child thread • If the main thread terminates, then all threads are killed! – Challenging questions! • Memory is shared by the parent and the child – nothing prevents the parent from modifying the memory (structure) while the child is still executing – which may lead to a wrong computation – we need to have synchronization mechanisms • After creating the child thread, the main thread continue. If it terminates before the completion of the child thread, the child will be killed. – Challenging questions!

Other pthread functions pthread_exit(): Terminates the calling thread. void pthread_exit(void *retval); – The return

Other pthread functions pthread_exit(): Terminates the calling thread. void pthread_exit(void *retval); – The return value is made available to another thread calling a pthread_join() – If a thread returns, the call to pthread_exit() is implicit

Other pthread functions The id of the thread to wait for pthread_join(): Causes the

Other pthread functions The id of the thread to wait for pthread_join(): Causes the calling thread to wait for another thread to terminate int pthread_join(pthread_t thread, void **value_ptr); Return 0 for success otherwise an error code output parameter, value given to pthread_exit()

Other pthread functions The id of the thread to terminate pthread_kill()Causes the termination of

Other pthread functions The id of the thread to terminate pthread_kill()Causes the termination of a thread int pthread_kill(pthread_t thread, int sig); Return 0 for success otherwise an error code