2011-01-05 35 views
6

Xin lỗi vì tiếng Anh của tôi - tôi là người Nga.Khóa mutex trong một chủ đề và mở khóa nó trong một số khác

Mã này có chính xác và di động không?

void* aThread(void*) 
{ 
    while(conditionA) 
    { 
     pthread_mutex_lock(mutex1); 
     //do something 
     pthread_mutex_unlock(mutex2); 
    } 
} 

void* bThread(void*) 
{ 
    while(conditionB) 
    { 
     pthread_mutex_lock(mutex2); 
     //do something 
     pthread_mutex_unlock(mutex1); 
    } 
} 

Thực tế trong ứng dụng đích, tôi có ba luồng - hai để viết mảng và một để đọc. Và tôi cần rằng ngay sau khi một trong những chủ đề thay đổi mảng thứ ba thread hiển thị nội dung của mảng.

Trả lời

10

Nó không phải là. Nếu chuỗi A được chuyển sang mutex_unlock (2) trước khi chuỗi B đã đến mutex_lock (2), bạn đang đối mặt với hành vi chưa xác định. Bạn không được mở khóa mutex của một thread khác.

Các pthread_mutex_lock Open Group Base Specification nói như vậy:

Nếu loại mutex là PTHREAD_MUTEX_NORMAL [...] Nếu một thread cố gắng để mở khóa một mutex rằng nó đã không bị khóa hoặc một mutex mà được mở khóa, kết quả hành vi không xác định.

+0

Ok. Nhưng những gì về mở khóa mutex đã bị khóa trong thread khác? Hành vi không xác định là tốt? –

+4

Như đã nói: "nếu một chuỗi cố gắng mở khóa một mutex mà nó không bị khóa ... UB" – user562374

3

user562734's answer says, câu trả lời là không - bạn không thể mở khóa chuỗi đã bị khóa bởi một chuỗi khác.

Để đạt được đồng bộ hóa trình đọc/ghi bạn muốn, bạn nên sử dụng các biến điều kiện - pthread_cond_wait(), pthread_cond_signal() và các chức năng liên quan.

+0

Semaphores đôi khi cũng hữu ích cho các tình huống mà bạn muốn có thể "mở khóa khóa của một sợi khác". Chúng thực sự là một giải pháp tuyệt vời cho thực tế là việc sử dụng 'pthread_atfork' được đề xuất trong tài liệu yêu cầu hành vi không xác định. :-) –

0

Một số triển khai cho phép khóa và mở khóa chuỗi thành khác nhau.

#include <iostream> 
#include <thread> 
#include <mutex> 

using namespace std; 

mutex m; 

void f() {m.lock(); cout << "f: mutex is locked" << endl;} 

void g() {m.unlock(); cout << "g: mutex is unlocked" << endl;} 

main() 
{ 
     thread tf(f); /* start f       */ 
     tf.join();  /* Wait for f to terminate   */ 
     thread tg(g); /* start g       */ 
     tg.join();  /* Wait for g to terminate   */ 
} 

Chương trình này in

f: mutex bị khóa g: mutex được mở khóa

Hệ thống là Debian Linux, gcc 4.9.1. -std = C++ 11.

+0

Việc triển khai gcc 4.9.1 có nói rõ ràng không? Nếu không và bạn đã có câu trả lời của bạn chỉ từ các thí nghiệm thì nó vẫn là UB, mặc dù trong trường hợp này nó dường như đang hoạt động. –

Các vấn đề liên quan