1 / 20

Threads

Explore processes and threads in computing, their trade-offs, POSIX threads, key functions like pthread_create and pthread_join, passing arguments to threads, thread safety considerations, and the use of pthread mutexes for synchronization. Learn about lightweight processes, program counters, shared memory, and more.

kroark
Download Presentation

Threads

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Threads CSCE 3600

  2. Thread Motivation • Processes are expensive to create. • Context switch between processes is expensive • Communication between processes must be done through an external structure • Files • Pipes, sockets • Shared memory • Process synchronization cumbersome. • What to do? Threads

  3. Threads of Execution • Program counter specifies next instruction • Sequence of executed instructions called program's thread of execution • Processes’ execution threads intermixed • Context switch

  4. Threads • Multiple execution threads can share process • Multiple flows of control within a process • Share code and data space of process • Lower overhead, avoid context switches • Each thread of execution is associated with a thread, an abstract data type representing the flow of control. • Sometimes called “lightweight processes”.

  5. Processes

  6. Threads

  7. Tradeoffs • Communication between threads is cheap • Threads can share variables! • Threads are “lightweight” • Faster to create • Faster to switch between • Need to avoid unwanted or unexpected interactions between threads.

  8. POSIX threads (pthreads) • The most commonly used thread package on Unix/Linux is POSIX threads (pthreads). • Thread package includes library calls for • Thread management (creation, destruction) • Mutual exclusion (synchronization, short-term locking) • Condition variables (waiting on events of unbounded duration) • A run-time system manages threads in a transparent manner so the user is unaware.

  9. pthread_create() int pthread_create(pthread_t *tid, pthread_attr_t *attr, void *(*func)(void *), void *arg); • tid uniquely identifies a thread within a process and is returned by the function • attr - sets attributes (e.g., priority, initial stack size), NULL for defaults) • func - the function to call to start the thread • accepts one void * argument, returns void * • arg is the argument to func • Returns 0 if successful, a positive error code if not • Does not set errno but returns compatible error codes • Can use strerror() to print error messages

  10. pthread_join() int pthread_join(pthread_t tid, void **thread_return) • tid – wait for a specific thread ID to terminate • Cannot wait for any thread (as in wait()) • Return value from a thread can be read in thread_return when it terminates. • A thread can terminate by: • Returning from func • The main() function exiting • pthread_exit()

  11. More functions void pthread_exit(void *status) • Terminate the thread, return status explicitly • status must not point to an object local to the thread, as these disappear when the thread terminates. int pthread_detach(pthread_t tid) • If a thread is detached its termination cannot be tracked with pthread_join() • It becomes a daemon thread pthread_t pthread_self(void) • Returns the thread ID of the thread which called it. • Often see pthread_detach(pthread_self())

  12. Passing arguments to threads pthread_t thread_ID; int fd, result; fd = open(“afile”, “r”); result = pthread_create(&thread_ID, NULL, myThreadFn, (void *) &fd); if(result != 0) printf("Error: %s\n", strerror(result)); • We can pass any variable (including a structure or array) to our thread function. • Assumes the thread function knows what type it is. • This example is bad if the main thread alters fd later.

  13. Example

  14. Example…

  15. A better approach

  16. Example… MyArg *p = (MyArg *) malloc(sizeof(MyArg)); p->fd = fd; /* assumes fd is defined */ strncpy(p->name, "CSCE3600", 7); result = pthread_create(&threadID, NULL, myThreadFcn, (void *) p); void *myThreadFcn(void *p) { MyArg *theArg = (MyArg *) p; write(theArg->fd, theArg->name, 7); close(theArg->fd); free(theArg); return NULL; }

  17. Thread Safety • The threads for a process share the entire address space of the process. • Can modify global variables, access open file descriptors, etc. (be careful when reusing variables passed by reference). • Need to ensure that multiple threads do not interfere with each other; synchronize thread execution. • A program or function is said to be thread safe if it can be called from multiple threads without unwanted interaction between the threads.

  18. Thread-safe functions • Not all functions can be called from threads • Many use global/static variables • Many functions have thread-safe replacements with_r suffix (e.g., strtok_r()). • Safe: • ctime_r(), gmtime_r(), localtime_r(), rand_r(), strtok_r() • Not safe: • ctime(), gmtime(), localtime(), rand(), strtok() • Could use semaphores to protect access but this generally results in poor performance.

  19. Pthread mutexes (semaphores) int pthread_mutex_init(pthread_mutex_t *mp, const pthread_mutexattr_t *attr); int pthread_mutex_lock(pthread_mutex_t *mp); int pthread_mutex_trylock(pthread_mutex_t *mp); int pthread_mutex_unlock(pthread_mutex_t *mp); int pthread_mutex_destroy(pthread_mutex_t *mp); • Easier to use than standard semaphores. • Only the thread that locks a mutex can unlock it. • Mutexes are often declared as global variables.

  20. Example

More Related