Một mutex là một cái gì đó bạn lấy, và sẽ ngăn chặn bất kỳ chủ đề khác cố gắng lấy nó cho đến khi bạn phát hành nó từ chủ đề grabbing.
Trong câu hỏi của bạn, bạn có một hàm f phân bổ một cá thể Mutex. Đó là không đủ để khóa nó. Bạn phải gọi cụ thể mutex.lock() (trong Qt, nhưng cũng nói chung, trừ khi bạn sử dụng pthread, trong trường hợp đó sử dụng pthread_mutex_lock và vui chơi với các công cụ phụ thuộc nền tảng thấp, phụ thuộc vào nền tảng. Qt tóm tắt nó rất tốt).
đây là một ví dụ với Qt
void MyClass::doStuff(int c)
{
mutex.lock();
a = c;
b = c * 2;
mutex.unlock();
}
khi bạn nhận được khóa, các cuộc gọi đến g() sẽ được thực hiện từ thread ai có khóa, vì vậy nó sẽ ở một mình ở chỗ gọi giả mà bạn không gọi g() từ các chủ đề khác từ một phần khác của mã. Khóa không có nghĩa là nó sẽ dừng tất cả các chủ đề khác. Nó sẽ ngăn chặn các chủ đề cố gắng để có được cùng một khóa, cho đến khi khóa được phát hành.
Nếu đó là cách duy nhất để các chủ đề của bạn đạt được g(), thì bạn được đồng bộ hóa trên quyền truy cập đó.
Đối với phần thứ hai của câu hỏi của bạn, Nếu mutex là một thuộc tính instance, thì chúng sẽ là hai mutex khác nhau. Bạn sẽ phải khai báo và khởi tạo một cá thể mutex lớp và tham chiếu đến nó cho khóa của bạn. Trong trường hợp đó, bất kỳ nỗ lực nào để gọi một phương thức trong lớp mà khóa lớp mutex sẽ được đồng bộ hóa một cách hiệu quả, nghĩa là không có hai luồng nào sẽ thực thi phương thức đó với nhau.
Ví dụ (Tôi không có Qt, vì vậy tôi không thể biên dịch mã này, và tôi dừng lại mã hóa với nó cách đây 2 năm, vì vậy nó không thể làm việc)
class Foo {
public:
void method(void) {
mutex.lock();
cout << "method called";
// long computation
mutex.unlock();
}
private:
QMutex mutex;
};
Ok, trong trường hợp này, giả sử bạn có hai luồng, 1 và 2 và hai trường hợp của lớp Foo, a và b. Giả sử rằng thread 1 gọi a.method() và thread 2 gọi b.method(). Trong trường hợp này, hai mutex là các cá thể khác nhau, do đó, mỗi luồng sẽ thực hiện cuộc gọi, độc lập và chạy song song.
Giả sử bạn có hai luồng, 1 và 2 và một phiên bản của lớp Foo được chia sẻ giữa hai luồng. nếu thread 1 gọi a.method() và sau đó thread 2 gọi a.method(), chuỗi 2 sẽ dừng lại và chờ cho đến khi khóa mutex được giải phóng.
Cuối cùng,
class Foo {
public:
void method(void) {
mutex.lock();
cout << "method called";
// long computation
mutex.unlock();
}
private:
static QMutex mutex;
};
QMutex Foo::mutex;
Trong trường hợp này, các mutex là một biến tĩnh lớp. Bạn chỉ có một thể hiện của mutex cho mỗi cá thể đối tượng. Giả sử bạn có tình huống tương tự như trường hợp đầu tiên ở trên: hai luồng và hai trường hợp. Trong trường hợp này, khi luồng thứ hai cố gắng gọi b.method(), nó sẽ phải chờ a.method() được hoàn thành bởi luồng đầu tiên, vì khóa bây giờ là duy nhất và được chia sẻ trong tất cả các phiên bản của lớp của bạn.
Mọi chi tiết, Qt có một hướng dẫn tốt đẹp về đa luồng
https://doc.qt.io/qt-5/threads.html
+1 sử dụng QT api –