Multithreaded Web Server
Rula et AquaLab 2 Threads –Allow multiple computation streams to run “in parallel” –Great for operations with blocking calls to the network or IO Types of threads –Kernel Threads –User Threads –Mapping between them – Linux 1:1
Rula et AquaLab 3 Synchronization –Allow resource and access control to multiple concurrent processes Semaphore –Send signals between processes –Binary, counting Mutex –Mutual Exclusion –Traditional Lock Condition Variables
Rula et AquaLab 4 struct sem { mutex m; condvar cv; unsigned int count; }; sem_init(s, value) { mutex_init(s.m); condvar_init(s.cv); count = value; } wait(s) { mutex_lock(s.m); while (s.count <= 0) { condvar_wait(s.cv, s.m); } --s.count; mutex_unlock(s.m); } post(s) { mutex_lock(s.m); ++s.count; condvar_broadcast(s.cv) mutex_unlock(s.m); }
Rula et AquaLab 5 Threadpools allow finite threads to be reused across multiple streams of execution Better performance –Eliminates overhead of thread creation and destruction –Reuse existing threads Typically consist of Worker Queue and Pool of Created Threads
Rula et AquaLab 6 Task Queue Thread Pool Completed Tasks
Rula et AquaLab 7 Task Queue Thread Pool Completed Tasks
Rula et AquaLab 8 POSIX Pthreads library core functions: Go here for tutorial: Threads pthread_create(thread,attr,start_routine,arg) pthread_exit(status) pthread_cancel(thread) pthread_join(threadid, status) Mutex pthread_mutex_init(mutex,attr) pthread_mutex_destroy(mutex) pthread_mutex_lock(mutex) pthread_mutex_unlock(mutex) Condition Variable pthread_cond_init(condition, attr) pthread_cond_destroy(condition) pthread_cond_wait(condition, mutex) pthread_cond_signal(condition)
Rula et AquaLab 9 Create thread pool –Easiest structure Worker queue with pending tasks Each threads running in loop When job is added to the pool, pthread_cond_signal(&(pool->notify)) Add locking to seats.c Standby List –Implement semaphore –More on this Check for job in queue if job, pull and run else wait on condition variable broadcast notify Check for job in queue...
Rula et AquaLab 10 Adding multithreading to webserver While(1) { connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); //without threads handle_connection(connfd); //with threads pool_add(threadpool, (void *) &handle_connection, (void *) connfd, 0); }
Rula et AquaLab 11 Condition Variables –Should be in a while loop to prevent race conditions Check for spurious wake-ups. When returning from pthread_cond_wait(), you own lock while((pool->count == 0) && (!pool->shutdown)) { pthread_cond_wait(&(pool->notify), &(pool->lock)); }
Rula et AquaLab 12 Only use a binary semaphore on the standby list –Implement semaphore but use it as a lock... –On the standby list data structure only Order of operations w/ standby list –When thread completes a job / wakes from condition variable, it first checks the standby list in the case that the previous operation freed the seat. If seat is Available, assign seat to that user If seat is Pending, do nothing If seat is Occupied, remove entry from the standby list