I have a multi-threaded application that creates 48 threads that all need to access a common attribute (stl :: map). The card will be recorded only when the streams begin, and the rest of the time the card will be read. This seems like the perfect use case for pthread_rw_lock, and everything seems to work well.
I ran into a completely unrelated seg error and started analyzing the kernel. Using gdb, I ran the info threads command and was very surprised by the results. I noticed that multiple threads are actually reading from the map, as expected, but the weird part is that multiple threads were blocked in pthread_rwlock_rdlock (), waiting on rw_lock.
Here is the stack trace for a thread waiting to block:
#0 0xffffe430 in __kernel_vsyscall ()
With so many threads, it’s hard to say how many were read and how many were blocked, but I don’t understand why any threads will be blocked, waiting for reading, given that other threads are already reading.
So, here is my question: why are some threads blocked to wait for rw_lock to read when other threads are already reading from it? It seems that there is a limit to the number of threads that can be read at one time.
Ive looked at the pthread_rwlock_attr_t functions and did not see anything related.
OS is Linux, SUSE 11.
Here is the related code:
{ pthread_rwlock_init(&serviceMapRwLock_, NULL); } // This method is called for each request processed by the threads Service *ServiceSingleton::getService(void *serviceId) { pthread_rwlock_rdlock(&serviceMapRwLock_); ServiceMapType::const_iterator iter = serviceMap_.find(serviceId); bool notFound(iter == serviceMap_.end()); pthread_rwlock_unlock(&serviceMapRwLock_); if(notFound) { return NULL; } return iter->second; } // This method is only called when the app is starting void ServiceSingleton::addService(void *serviceId, Service *service) { pthread_rwlock_wrlock(&serviceMapRwLock_); serviceMap_[serviceId] = service; pthread_rwlock_unlock(&serviceMapRwLock_); }
Update:
As mentioned in MarkB's comments, if I set pthread_rwlockattr_getkind_np () to give priority to writers, and there is a wait lock script, then the observed behavior would make sense. But, I use the default value, which, I believe, gives priority to readers. I just checked that there are no threads blocked for writing. I also update the code suggested by @Shahbaz in the comments and get the same results.