2011-10-19 32 views
8

Tôi nhận được lỗi phụ đề trong trình phá hủy mutex. vì lỗi có thể do mutex ở trạng thái khóa trong quá trình hủy, tôi tạo một lớp mutex mới được thừa hưởng từ boost: mutex. nó là để đảm bảo mutex được mở khóa trong quá trình hủy diệt. Tuy nhiên, lỗi tương tự vẫn xảy ra. Bất kỳ lượt truy cập nào sẽ được đánh giá cao!boost :: mutex :: ~ mutex(): Xác nhận `! Pthread_mutex_destroy (& m) 'không thành công

class CMutes : public boost::mutex 
{ 
public: 
    CMutes() 
    { 

    }; 

    virtual ~CMutes() 
    { 
     if (m_bLock) 
      boost::mutex::unlock(); 
    }; 

    void lock() 
    { 
     if(!m_bLock) 
      boost::mutex::lock(); 
     else 
      cout << "Mutex is in lock state\n"; 
    }; 

    void unlock() 
    { 
     if (m_bLock) 
      boost::mutex::unlock(); 
     else 
      cout << "Mutex is in unlock state\n"; 
    } 

    boost::mutex& getMutex() 
    { 
     return *this; 
    } 

private: 

    bool m_bLock; 
}; 

EDIT: Có bạn đúng. Tôi nên sử dụng RAII. Tuy nhiên, tôi đang ở trong một tình huống. Tôi cần khóa một tài nguyên trước khi một luồng khác kết thúc xử lý nó. một cái gì đó như dưới đây.

Thread A: 
void getDate() 
{ 
m_oLock.lock(); 
// access resource 
} 

void unlock() 
{ 
m_oLock.unlock(); 
} 
Thread B: 
void Process() 
{ 
threadA.getData(); 
threadA.unlock(); 
} 

Trả lời

7

Do Not kế thừa từ boost::mutex, lớp boost::mutex không có một destructor ảo, vì vậy nó không thực sự có nghĩa là cho thừa kế.

Root Cause có thể:
Các lỗi mà bạn đang nhận được chỉ ra rằng bạn đang gọi unlock trên một mutex mà chưa bao giờ bị khóa. Một cái gì đó như:

boost::mutex m; 
m.unlock(); 

Bằng cách cố gắng làm lockunlock, có vẻ như bạn bị mất theo dõi xem các mutex như locked.This là rất thường xuyên vấn đề khi bạn thực hiện quản lý tài nguyên bằng tay. C++ cho phép một mechansim cụ thể được gọi là Resource Allocation is Initilization(RAII) để bảo vệ an toàn chống lại các vấn đề như vậy.

Suggestted Giải pháp:
Bạn nên sử dụng RAII, chứ không phải là mở khóa mutex một cách rõ ràng. Bạn có thể sử dụng boost :: mutex :: scoped_lock để thực hiện RAII:

struct YourStruct 
{ 
    void doSomething() 
    { 
     boost::mutex::scoped_lock l(m_mutex); 
     //do something Interesting 
    } 
    private: 
     boost::mutex m_mutex; 
}; 
+1

Tôi xin lỗi. từ lõi, nó chỉ ra rằng nó thất bại trong destructor của mutex. Và vâng. nó chỉ là một thử nghiệm để chứng minh rằng mutex đang ở trạng thái mở khóa. # 0 0x0000003803030265 trong việc tăng() từ /lib64/libc.so.6 (gdb) trong đó # 0 0x0000003803030265 tăng() từ /lib64/libc.so.6 # 1 0x0000003803031d10 trong hủy bỏ() từ /lib64/libc.so.6 # 2 0x00000038030296e6 trong __assert_fail() từ/lib64/libc.so.6 # 3 0x0000000000416314 trong tăng :: mutex :: ~ mutex()() –

2

POSIX khẳng định rằng các lỗi chỉ trở về từ một hoạt động pthread_mutex_destroyEINVAL nếu mutex là bằng cách nào đó không hợp lệ, hoặc EBUSY nếu ai đó sử dụng nó (một cách rõ ràng hoặc thông qua các biến điều kiện).

Kịch bản có khả năng nhất là trường hợp thứ hai.

Tuy nhiên, tôi không thấy bất kỳ thay đổi nào đối với biến thành viên m_bLock trong bất kỳ mã nào của bạn. Bạn có chắc chắn không muốn thay đổi biến này trong các cuộc gọi lockunlock không?

Nếu nó đang sử dụng, bạn sẽ chỉ phải đợi cho đến khi bất kỳ ai đang sử dụng nó sẵn sàng phát hành. Bất kỳ tùy chọn nào khác cũng không phù hợp với bạn :-)

+0

vậy làm thế nào để in ra các errno trong destructor? liên quan đến m_bLock, lớp khác sẽ gọi chức năng khóa và mở khóa để m_bLock được thay đổi. Những gì tôi đã làm là chỉ để đảm bảo rằng mutex đang ở trạng thái mở khóa. Và trong destructor, mutex không cần phải mở khóa trong quá trình thử nghiệm của tôi có nghĩa là mutex đang ở trạng thái mở khóa –

+0

@Michael, đó là một điểm tốt, tôi vừa nhận ra rằng bạn sẽ phải khẳng định trước khi trở về, vì vậy bạn sẽ không nhận được cơ hội để in ra errno (pax giận dữ chỉnh sửa câu trả lời của mình). Với điểm thứ hai của bạn, mặc dù mã có thể _call_ 'khóa/mở khóa', điều đó không thay đổi' mbLock' vì các hàm thành viên của bạn không bao giờ thay đổi nó. – paxdiablo

3

Tôi đã gặp lỗi tương tự (đó là cách tôi tìm thấy câu hỏi này). Tôi đã giải quyết vấn đề bằng cách thêm một số join vào chuỗi liên quan. Quá trình chính của tôi đã kết thúc trước khi chuỗi đã được thực hiện và mutex đã bị rách trước khi nó có thể được mở khóa.

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