Tôi có một ứng dụng đa luồng tạo 48 chủ đề mà tất cả đều cần truy cập vào một thuộc tính chung (stl :: map). Bản đồ sẽ chỉ được ghi khi chủ đề bắt đầu và phần còn lại của bản đồ sẽ được đọc từ đó. Điều này có vẻ giống như trường hợp sử dụng hoàn hảo cho một pthread_rw_lock, và tất cả dường như hoạt động tốt.Có bao nhiêu người đọc đồng thời một pthread_rwlock có?
Tôi đã chạy qua một lỗi seg hoàn toàn không liên quan và bắt đầu phân tích lõi. Sử dụng gdb, tôi thực hiện lệnh info threads
và khá ngạc nhiên về kết quả. Tôi quan sát thấy rằng một số chủ đề đã thực sự đọc từ bản đồ như mong đợi, nhưng phần lạ là một số chủ đề đã bị chặn trong pthread_rwlock_rdlock() chờ đợi trên rw_lock.
Đây là stack trace cho một thread đang chờ đợi trên khóa:
#0 0xffffe430 in __kernel_vsyscall()
#1 0xf76fe159 in __lll_lock_wait() from /lib/libpthread.so.0
#2 0xf76fab5d in pthread_rwlock_rdlock() from /lib/libpthread.so.0
#3 0x0804a81a in DiameterServiceSingleton::getDiameterService(void*)()
Với rất nhiều chủ đề, nó khó có thể nói bao nhiêu người đã đọc và bao nhiêu đã bị chặn, nhưng tôi không hiểu tại sao bất kỳ số nào chủ đề sẽ bị chặn đang chờ đọc, xem xét các chủ đề khác đã đọc.
Vì vậy, đây là câu hỏi của tôi: Tại sao một số chủ đề bị chặn chờ đợi để đọc một rw_lock, khi các chủ đề khác đã đọc từ nó? Nó xuất hiện như thể có một giới hạn về số lượng các chủ đề có thể đọc đồng thời.
Ive đã xem các chức năng pthread_rwlock_attr_t
và không thấy bất kỳ điều gì có liên quan.
Hệ điều hành Linux, SUSE 11.
Đây là mã có liên quan:
{
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_);
}
Cập nhật:
Như đã đề cập trong các ý kiến của MarkB, nếu tôi đã thiết lập pthread_rwlockattr_getkind_np() để ưu tiên cho các nhà văn, và có một nhà văn bị chặn chờ đợi, sau đó hành vi được quan sát sẽ có ý nghĩa. Nhưng, Im sử dụng giá trị mặc định mà tôi tin là ưu tiên cho người đọc. Tôi vừa xác minh rằng có không chủ đề bị chặn đang chờ để viết. Tôi cũng cập nhật mã theo gợi ý của @Shahbaz trong các nhận xét và nhận được kết quả tương tự.
Bạn * chắc chắn * rằng không có khóa chặn người viết nào? –
@MarkB Đó là một câu hỏi tuyệt vời! Nhưng doesnt mà phụ thuộc vào pthread_rwlockattr_getkind_np() mà tôi havent gọi? Im không chắc chắn nếu bất kỳ chủ đề đang chờ để viết, nhưng họ không nên kể từ đó chỉ nên xảy ra ở đầu. Tôi sẽ phải kiểm tra mặc dù. – Brady
@MarkB, điều gì sẽ ảnh hưởng đến điều gì nếu một người viết đang đợi và tôi đã không đặt pthread_rwlockattr_getkind_np()? Theo tôi hiểu, người viết có thể bị bỏ đói nếu có người đọc liên tục, đúng không? – Brady