Presentation is loading. Please wait.

Presentation is loading. Please wait.

Programming with Threads. Threads  Sometimes called a lightweight process  smaller execution unit than a process  Consists of:  program counter 

Similar presentations


Presentation on theme: "Programming with Threads. Threads  Sometimes called a lightweight process  smaller execution unit than a process  Consists of:  program counter "— Presentation transcript:

1 Programming with Threads

2 Threads  Sometimes called a lightweight process  smaller execution unit than a process  Consists of:  program counter  register set  stack space  Threads share:  memory space  code section  OS resources(open files, signals, etc.)  Sometimes called a lightweight process  smaller execution unit than a process  Consists of:  program counter  register set  stack space  Threads share:  memory space  code section  OS resources(open files, signals, etc.)

3 Threads  A process is defined to have at least one thread of execution  A process may launch other threads which execute concurrently with the process  Switching between threads is faster  No memory management issues, etc.  Mutual exclusion problems:  A process is defined to have at least one thread of execution  A process may launch other threads which execute concurrently with the process  Switching between threads is faster  No memory management issues, etc.  Mutual exclusion problems:

4 Threads Process 0 code mem regs Process 1 code mem regs All threads in a process share the same memory space

5 Single Threaded and Multithreaded Process Models Thread Control Block User Stack User Stack Kernel Stack Kernel Stack User Address Space User Address Space Process Control Block Process Control Block Thread Single-Threaded Process Model Multithreaded Process Model Thread Control Block User Stack Kernel Stack Thread Control Block User Stack Kernel Stack Thread

6 Why Threads?  Software Portability  Latency Hiding  Scheduling and Load Balancing  Speed  Ease of Programming and Widespread use  Program Maintenance  Software Portability  Latency Hiding  Scheduling and Load Balancing  Speed  Ease of Programming and Widespread use  Program Maintenance

7

8

9 Thread issues  How should threads be scheduled compared to processes?  Equal to processes  Within the parent processes quantum  How are threads implemented  kernel support (system calls)  user level threads  What are the issues?  How should threads be scheduled compared to processes?  Equal to processes  Within the parent processes quantum  How are threads implemented  kernel support (system calls)  user level threads  What are the issues?

10

11 User-Level Threads  All thread management is done by the application  The kernel is not aware of the existence of threads  Thread switching does not require kernel mode privileges  Scheduling is application specific  All thread management is done by the application  The kernel is not aware of the existence of threads  Thread switching does not require kernel mode privileges  Scheduling is application specific

12 Kernel-Level Threads  Windows NT and Linux are examples of this approach  Kernel maintains context information for the process and the threads  Switching between threads requires the kernel  Windows NT and Linux are examples of this approach  Kernel maintains context information for the process and the threads  Switching between threads requires the kernel

13 POSIX Threads  Thread API available on many OS’s  #include  cc myprog.c –o myprog -lpthread  Thread creation  int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg);  Thread termination  void pthread_exit(void *retval);  Waiting for Threads  int pthread_join(pthread_t th, void **thread_return);  Thread API available on many OS’s  #include  cc myprog.c –o myprog -lpthread  Thread creation  int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg);  Thread termination  void pthread_exit(void *retval);  Waiting for Threads  int pthread_join(pthread_t th, void **thread_return);

14 #include int print_message_function( void *ptr ); int x = 1; main() { pthread_t thread1, thread2; int thread1result, thread2result; char *message1 = "Hello"; char *message2 = "World"; pthread_attr_t *pthread_attr_default = NULL; printf("Begin\n"); pthread_create( &thread1, pthread_attr_default, (void*)&print_message_function, (void*) message1); pthread_create(&thread2, pthread_attr_default, (void*)&print_message_function, (void*) message2); pthread_join(thread1, (void *)&thread1result); printf("End thread1 with %d\n", thread1result); pthread_join(thread2, (void *)&thread2result); printf("End thread2 with %d\n", thread2result); exit(0); } int print_message_function( void *ptr ) { char *message; message = (char *) ptr; printf("%s ", message); fflush(stdout); return x++; }

15 #include server() { SOCKET listenSkt, newSkt; struct sockaddr_in serverName, clientName; listenSkt = socket(AF_INET, SOCK_STREAM, 0); //Fill in serverName bind(listenSkt, &serverName, sizeof(serverName)); listen(listenSkt, 5); newSkt = accept(listenSkt, &clientName, sizeof(clientName)); // Fire off a thread to do communication using send and recv on newSkt // Loop back and accept another connection close(skt); } #include server() { SOCKET listenSkt, newSkt; struct sockaddr_in serverName, clientName; listenSkt = socket(AF_INET, SOCK_STREAM, 0); //Fill in serverName bind(listenSkt, &serverName, sizeof(serverName)); listen(listenSkt, 5); newSkt = accept(listenSkt, &clientName, sizeof(clientName)); // Fire off a thread to do communication using send and recv on newSkt // Loop back and accept another connection close(skt); }

16 typedef struct myarg { int skt; int whatever; }MyArg; … pthread_attr_t *default = NULL; MyArg *arg; while (!done) { newSkt = accept(listenSkt, &clientName, sizeof(clientName)); // Allocate and fill the argument structure arg = (MyArg *)malloc(sizeof(MyArg)); arg->skt = newSkt; // Fire off a thread to do communication using send and recv on newSkt pthread_create(&threads[j], default, HandleConnection, (void *)arg); } typedef struct myarg { int skt; int whatever; }MyArg; … pthread_attr_t *default = NULL; MyArg *arg; while (!done) { newSkt = accept(listenSkt, &clientName, sizeof(clientName)); // Allocate and fill the argument structure arg = (MyArg *)malloc(sizeof(MyArg)); arg->skt = newSkt; // Fire off a thread to do communication using send and recv on newSkt pthread_create(&threads[j], default, HandleConnection, (void *)arg); }

17 typedef struct myarg { int skt; int whatever; }MyArg; … void *HandleConnection(void *arg) { int skt; char buffer[255]; // Don’t do this!!!! Allocate as much as you need! skt = (MyArg *)arg->skt; recv(skt, buffer, bufflen, 0);// Wrap this in a while loop // Process the message send(skt, response, responselength, 0); } typedef struct myarg { int skt; int whatever; }MyArg; … void *HandleConnection(void *arg) { int skt; char buffer[255]; // Don’t do this!!!! Allocate as much as you need! skt = (MyArg *)arg->skt; recv(skt, buffer, bufflen, 0);// Wrap this in a while loop // Process the message send(skt, response, responselength, 0); }

18 Thread Issues  Thread function only gets  One void * argument and void * return  How do you do more?  Reentrance  False Sharing  Not same global variable, but within cache line  Mutual Exclusion  Thread function only gets  One void * argument and void * return  How do you do more?  Reentrance  False Sharing  Not same global variable, but within cache line  Mutual Exclusion

19 Effects of False Sharing Multiple Threads Writing to two variables Placement local stack variables Right next to each other 16 words apart 32 words apart Multiple Threads Writing to two variables Placement local stack variables Right next to each other 16 words apart 32 words apart Local variables Shared variables In Same Cache Line

20 Synchronization Primitives  int pthread_mutex_init( pthread_mutex_t *mutex_lock, const pthread_mutexattr_t *lock_attr);  int pthread_mutex_lock( pthread_mutex_t *mutex_lock);  int pthread_mutex_unlock( pthread_mutex_t *mutex_lock);  int pthread_mutex_trylock( pthread_mutex_t *mutex_lock);  int pthread_mutex_init( pthread_mutex_t *mutex_lock, const pthread_mutexattr_t *lock_attr);  int pthread_mutex_lock( pthread_mutex_t *mutex_lock);  int pthread_mutex_unlock( pthread_mutex_t *mutex_lock);  int pthread_mutex_trylock( pthread_mutex_t *mutex_lock);

21 #include void *find_min(void *list_ptr) pthread_mutex_t minimum_value_lock; int minimum_value, partial_list_size; main(){ minimum_value = MIN_INT; pthread_init(); pthread_mutex_init(&minimum_value_lock, NULL); /*inititalize lists etc, create and join threads*/ } void *find_min(void *list_ptr){ int *partial_list_ptr, my_min = MIN_INT, i; partial_list_ptr = (int *)list_ptr; for (i = 0; i < partial_list_size; i++) if (partial_list_ptr[i] < my_min) my_min = partial_list_ptr[i]; pthread_mutex_lock(minimum_value_lock); if (my_min < minimum_value) minimum_value = my_min; pthread_mutex_unlock(minimum_value_lock); pthread_exit(0); }

22 Locking Overhead  Serialization points  Minimize the size of critical sections  Be careful  Rather than wait, check if lock is available  Pthread_mutex_trylock  If already locked, will return EBUSY  Will require restructuring of code  Serialization points  Minimize the size of critical sections  Be careful  Rather than wait, check if lock is available  Pthread_mutex_trylock  If already locked, will return EBUSY  Will require restructuring of code

23 /* Finding k matches in a list */ void *find_entries(void *start_pointer) { /* This is the thread function */ struct database_record *next_record; int count; current_pointer = start_pointer; do { next_record = find_next_entry(current_pointer); count = output_record(next_record); } while (count < requested_number_of_records); } int output_record(struct database_record *record_ptr) { int count; pthread_mutex_lock(&output_count_lock); output_count ++; count = output_count; pthread_mutex_unlock(&output_count_lock); if (count <= requested_number_of_records) print_record(record_ptr); return (count); }

24 /* rewritten output_record function */ int output_record(struct database_record *record_ptr) { int count; int lock_status; lock_status=pthread_mutex_trylock(&output_count_lock); if (lock_status == EBUSY) { insert_into_local_list(record_ptr); return(0); } else { count = output_count; output_count += number_on_local_list + 1; pthread_mutex_unlock(&output_count_lock); print_records(record_ptr, local_list, requested_number_of_records - count); return(count + number_on_local_list + 1); }


Download ppt "Programming with Threads. Threads  Sometimes called a lightweight process  smaller execution unit than a process  Consists of:  program counter "

Similar presentations


Ads by Google