Threads

  • Uploaded by: abdullah samdi
  • 0
  • 0
  • December 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Threads as PDF for free.

More details

  • Words: 2,006
  • Pages: 23
CE 466 System Programming

Threads

Computer Engineering Department Yarmouk University 11/30/2008

What is a Threads • An encapsulation of a flow of control in a program • A light weight process • Shares an address space and other resources • Cheaper context switching cost

• Multi threaded programs run through multiple code paths simultaneously • Natural for implementing tasks that can be broken into subtasks that may run cooperatively

1

What is a Threads • A thread is a semi-process, that has its own stack, and executes a given piece of code • Threads exists within a process • Multiple strands of execution in a single program • A mechanism to allow a program do more than one thing at a time (appear to run concurrently) • Thread Group is a set of threads all executing inside the same process

Processes vs. Threads • Created threads share same • Memory space (code, static and global variables, heap) • Process attributes held by the kernel ( User ID, current directory, file descriptors)

• Threads have their own: • Registers and stack, ID, priority level

• Overhead of creating a new thread is significantly less than when creating a new process • Switching between threads requires much less work than switching between processes

2

Processes vs. Threads • Threads demand much less resources than processes do • Writing multithreaded programs could be tricky: • Subtle faults (timing, sharing variables) • Thread synchronization and mutual exclusions is the programmer responsibility • Harder to debug a multithreaded program • exec() in a process vs. a thread

Thread Execution

3

Thread Pros and Cons • Pros: • • • •

Responsiveness Resource Sharing Economy Utilization of MP Architectures

• Cons: • Extra caution when programming threads • Complexity of extending process concepts (e.g. when forking a process should all threads be created? How are signals handled?)

Multithreading Models •

Support for threads may be provided either at the user or kernel levels: •





User Level: supported by the thread library above the kernel (all management code and data structures in user space) Kernel Level: supported directly by the operating system (all management code and data structures in the kernel space)

A relation exists between the two

4

Multithreading Models •

Many-to-One: • • • • •

Many user-level threads mapped to single kernel thread Managed in the user space by the thread library (efficient) Used on systems that do not support kernel threads Entire process blocks in case one of its threads block (-ve) True concurrency is not fully achieved (-ve)

Multithreading Models •

One-to-One: • • • •

Each user-level thread maps to kernel thread A process does not block if one of its threads block Better utilizes multiprocessors (each thread runs on its own processor) Too many threads consume system resources (-ve)

5

Multithreading Models • Many-to-Many: • Multiplexes user threads to a smaller or equal number of kernel threads • Developer can create as many user threads • The corresponding kernel threads can run in parallel on a multiprocessor

Servers and Thread Pools • A server receives requests and creates threads to service these requests: • Cost of creating a thread? • Cost of discarding a thread? • How many total threads can/should be created?

• Create a number of threads at process startup and let them wait for work

6

Thread families • Three families of mainstream threads are available: • POSIX-style: run on Unix (like) systems (e.g. Pthreads) • Microsoft-style threads: run on Windows (e.g. Win32) • Java threads: run on a variety of operating systems

• Other programming languages have their own way of handling threads (Perl, Python, Ruby,…)

POSIX Threads • The idea of threads has been around for some time but not standardized • The IEEE POSIX committee published the 1003.1c specifications (thread creation and synchronization) • Linux implements the POSIX standard thread API (Pthreads)

7

POSIX Threads • The Pthread functions are not included in the standard C librarybut in libpthread.a • You should add “-lpthread” to the command line when you link your program which implements threads.

Thread Manipulation 1. Thread creation • •

Each thread is identified by a thread ID Upon creation, a thread executes a function • •



The function takes a single parameter of type void* (can be used to pass data to the thread) The function returns void* (can be used to pass data from thread back to creator process)

Thread attributes control details of how the thread interacts with the rest of the program

8

Thread Creation thread ID is stored

NULL: default attributes

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

thread function Passed as argument to thread function

Thread Creation • The call to ‘pthread_create’ returns immediately • The original thread continues executing the instructions following the call • Meanwhile, the new thread begins executing the thread function • Linux schedules both threads asynchronously • No order of execution is guaranteed

9

Thread Attributes • pthread_attr_t object encapsulates properties such as: stack size, scheduling policy, detach state, cancelation state • These attributes affect a thread only at the time of attribute objects …………… creation state

……………

stack

…………… pthread_attr_getstack pthread_attr_setstack

Scheduling

…………… pthread_attr_getschedparam pthread_attr_setschedparam pthread_attr_getschedpolicy pthread_attr_setschedpolicy ……………

Thread Manipulation 2. Thread termination •

Causes the current thread to exit and free any threadspecific resources it is taking Usually NULL, anything else might be out of scope

int pthread_exit ( void *Value );



Useful if we want to exit a thread in the middle of its execution

10

Example 1 #include #include <stdio.h> void* Display_0s (void* NoValue) { while(1) fputc (‘0 ’,stderr); return NULL; } Void main () { pthread_t thread_id; pthread_create (&thread_id,NULL,&Display_0s,NULL); while(1) fputc (‘1 ’,stderr); }

Example 2 #include <stdio.h> struct char_print_parms { char character; int count; }; void* Char-Print (void* params) { struct char_print_parms* p=(struct char_print_parms*)params; int i, LocalCount; LocalCount = p->count; for (i = 0 ; i < LocalCount ; i++) fputc (p->character, stderr); return NULL; }

11

Example 2 #include #include <stdio.h> void main () { pthread_t thread_1, thread_2; struct char_print_parms thread_1_args; struct char_print_parms thread_2_args; thread_1_args.character =’0 ’; thread_1_args.count = 1000; pthread_create (&thread_1,NULL,&char_print,&thread_1_args); thread_2_args.character =’1 ’; thread_2_args.count = 2000; pthread_create (&thread_2,NULL,&char_print,&thread_2_args); }

Main thread may terminate before the other threads do: Local variables will be deallocated and inaccessible by threads 1 and 2

Thread Manipulation 3. Joining threads •

Suspends the calling thread until target thread terminates

int pthread_join( pthread_t thread,

thread ID to wait for

void **thread_return)

receive the finished thread’s return value (NULL if not important)

12

Example 2 #include #include <stdio.h> void main () { pthread_t thread_1, thread_2; struct char_print_parms thread_1_args; struct char_print_parms thread_2_args; thread_1_args.character =’0 ’; thread_1_args.count = 1000; pthread_create (&thread_1,NULL,&char_print,&thread_1_args); thread_2_args.character =’1 ’; thread_2_args.count = 2000; pthread_create (&thread_2,NULL,&char_print,&thread_2_args); }

pthread_join (thread_1,NULL); pthread_join (thread_2,NULL);

Example 3 #include <stdio.h> #include #include <stdlib.h> #include char message[] = “Hello World”; void *thread_function(void *arg) { printf(“thread_function is running. Argument was %s\n”, (char *)arg); sleep(3); strcpy(message, “Bye!”); pthread_exit(“Thank you for the CPU time”); }

13

Example 3 int main() { int res; pthread_t a_thread; void *thread_result; res = pthread_create(&a_thread, NULL, thread_function, (void *)message); if (res != 0) { perror(“Thread creation failed”); exit(EXIT_FAILURE); } printf(“Waiting for thread to finish...\n”); res = pthread_join(a_thread, &thread_result); if (res != 0) { perror(“Thread join failed”); exit(EXIT_FAILURE); } printf(“Thread joined, it returned %s\n”, (char *)thread_result); printf(“Message is now %s\n”, message); exit(EXIT_SUCCESS); }

Other Thread Functions •

Pthread_t pthread_self(): •



Returns the id of the thread in which it is called.

Pthread_t pthread_equal (pthread_t x, pthread_t y): •



Compares a thread id (x) with another (y)

int pthread_detach(pthread_t thread): •



Resources of a thread can be reclaimed when a thread terminates (detached vs. joinable thread)

int pthread_cancel(pthread_t thread) • •

Cancels the thread ‘thread’ A thread may be asynchronously cancelable; synchronously cancelable; uncancelable

14

Example 4 #include void* thread_function (void* thread_arg) { /* Do work here... */ } int main () { pthread_attr_t attr; pthread_t thread; pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); pthread_create (&thread, &attr, &thread_function, NULL); pthread_attr_destroy (&attr); /* Do work here... */ /* No need to join the second thread. */ return 0; }

User vs. Kernel-Level Threads User User manages threads

Kernel Kernel creates and manages threads A thread may monopolize Kernel schedules each the time slice of the process thread within the time slice of a process Switching is fast Switching has more overhead

15

Java Example class SimpleThread extends Thread { public SimpleThread(String str) { super(str); } public void run() { for (int i = 0; i < 10; i++) { System.out.println(i + " " + getName()); try { sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) {} } System.out.println("DONE! " + getName()); } }

Java Example class TwoThreadsTest { public static void main (String args[]) { new SimpleThread("Jamaica").start(); new SimpleThread("Fiji").start(); } }

16

Java Example 0 Jamaica 0 Fiji 1 Fiji 1 Jamaica 2 Jamaica 2 Fiji 3 Fiji 3 Jamaica 4 Jamaica 4 Fiji 5 Jamaica 5 Fiji 6 Fiji 6 Jamaica 7 Jamaica 7 Fiji 8 Fiji 9 Fiji 8 Jamaica DONE! Fiji 9 Jamaica DONE! Jamaica

Synchronization (Mutexes) • • •



Mutual Exclusion locks A special lock that only one thread may lock at a time If a second thread tries to lock an already locked mutex and then a the second thread is put on hold (blocked) When the first thread unlocks the mutex the second thread is allowed to resume execution (unblocked)

17

Synchronization (Mutexes) • #include • pthread_mutex_t mutex; • int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t • *mutexattr); • int pthread_mutex_lock(pthread_mutex_t *mutex)); • int pthread_mutex_unlock(pthread_mutex_t *mutex); • int pthread_mutex_destroy(pthread_mutex_t *mutex);

Example 5 #include <stdio.h> #include #include <stdlib.h> #include <string.h> #include #include <semaphore.h> pthread_mutex_t work_mutex; /* protects both work_area and time_to_exit */ #define WORK_SIZE 1024 char work_area[WORK_SIZE]; int time_to_exit = 0;

18

Example 5 void *thread_function(void *arg) { sleep(1); pthread_mutex_lock(&work_mutex); while(strncmp(“end”, work_area, 3) != 0) { printf(“You input %d characters\n”, strlen(work_area) -1); work_area[0] = ‘\0’; pthread_mutex_unlock(&work_mutex); sleep(1); pthread_mutex_lock(&work_mutex); while (work_area[0] == ‘\0’ ) { pthread_mutex_unlock(&work_mutex); sleep(1); pthread_mutex_lock(&work_mutex); } } time_to_exit = 1; work_area[0] = ‘\0’; pthread_mutex_unlock(&work_mutex); pthread_exit(0); }

Example 5 int main() { int res; pthread_t a_thread; void *thread_result; res = pthread_mutex_init(&work_mutex, NULL); if (res != 0) { perror(“Mutex initialization failed”); exit(EXIT_FAILURE); } res = pthread_create(&a_thread, NULL, thread_function, NULL); if (res != 0) { perror(“Thread creation failed”); exit(EXIT_FAILURE); } pthread_mutex_lock(&work_mutex); printf(“Input some text. Enter ‘end’ to finish\n”);

19

Example 5 while(!time_to_exit) { fgets(work_area, WORK_SIZE, stdin); pthread_mutex_unlock(&work_mutex); while(1) { pthread_mutex_lock(&work_mutex); if (work_area[0] != ‘\0’) { pthread_mutex_unlock(&work_mutex); sleep(1); } else { break; } } } pthread_mutex_unlock(&work_mutex); printf(“\nWaiting for thread to finish...\n”); res = pthread_join(a_thread, &thread_result); if (res != 0) { perror(“Thread join failed”); exit(EXIT_FAILURE); } printf(“Thread joined\n”); pthread_mutex_destroy(&work_mutex); exit(EXIT_SUCCESS); }

Synchronization (Semaphores) #include <semaphore.h> • int sem_init(sem_t *sem, int pshared, unsigned int value); • int sem_wait(sem_t * sem); • int sem_post(sem_t * sem); • int sem_destroy(sem_t * sem);

20

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

Initializes a semaphore object pointed to by sem • pshared parameter controls the type of semaphore (0 means local to current process) • value gives the semaphore an initial integer value

Control Functions int sem_wait(sem_t * sem); • Atomically decreases the value of the semaphore by 1 (waits until the semaphore has a nonzero count first) int sem_post(sem_t * sem); • Atomically increases the value of the semaphore by 1

21

Control Functions int sem_wait(sem_t * sem); • Atomically decreases the value of the semaphore by 1 (waits until the semaphore has a nonzero count first)

Example 5 sem_t bin_sem; #define WORK_SIZE 1024 char work_area[WORK_SIZE]; void *thread_function(void *arg) { sem_wait(&bin_sem); while(strncmp(“end”, work_area, 3) != 0) { printf(“You input %d characters\n”, strlen(work_area) -1); sem_wait(&bin_sem); } pthread_exit(NULL); }

22

Example 5 int main() { int res; pthread_t a_thread; void *thread_result; res = sem_init(&bin_sem, 0, 0); res = pthread_create(&a_thread, NULL, thread_function, NULL); printf(“Input some text. Enter ‘end’ to finish\n”); while(strncmp(“end”, work_area, 3) != 0) { fgets(work_area, WORK_SIZE, stdin); sem_post(&bin_sem); } printf(“\nWaiting for thread to finish...\n”); res = pthread_join(a_thread, &thread_result); printf(“Thread joined\n”); sem_destroy(&bin_sem); exit(EXIT_SUCCESS); }

23

Related Documents

Threads
December 2019 37
Threads
May 2020 26
Threads
April 2020 15
Threads
June 2020 13
Threads
October 2019 28
Threads
July 2020 18

More Documents from ""

Programming Under Unix
December 2019 21
Process Management(unix)
December 2019 19
Pc Pipes(unix)
December 2019 23
Threads
December 2019 37