Tôi nghĩ rằng nó trừu tượng xấu cũng như đóng gói không tốt. a mutex
thường được xây dựng mặc định với các hàm tạo bản sao bị xóa, có nhiều đối tượng mutex tham chiếu đến cùng một đối tượng lôgic dễ bị lỗi, tức là nó có thể dẫn đến deadlocks và các điều kiện chủng tộc khác vì lập trình viên hoặc người đọc có thể giả định rằng chúng là các thực thể khác nhau.
Hơn nữa bằng cách chỉ định mutex nội bộ nào bạn đang sử dụng, bạn sẽ hiển thị chi tiết triển khai các chuỗi của bạn, do đó phá vỡ lớp trừu tượng của lớp Mutex. Nếu bạn đang sử dụng pthread_mutex_t
thì rất có thể bạn sẽ sử dụng các chuỗi hạt nhân (pthreads).
Việc đóng gói cũng bị hỏng vì Mutex của bạn không phải là một thực thể được đóng gói duy nhất mà nằm rải rác thành một số tham chiếu (có thể đang lơ lửng).
Nếu bạn muốn để đóng gói một pthread_mutex_t
vào một lớp học mà bạn sẽ làm điều đó như vậy
class Mutex {
public:
void lock();
void unlock();
// Default and move constructors are good!
// You can store a mutex in STL containers with these
Mutex();
Mutex(Mutex&&);
~Mutex();
// These can lead to deadlocks!
Mutex(const Mutex&) = delete;
Mutex& operator= (const Mutex&) = delete;
Mutex& operator= (Mutex&&) = delete;
private:
pthread_mutex_t internal_mutex;
};
đối tượng Mutex có nghĩa là để được chia sẻ trong một phạm vi chia sẻ công bố trong các tập tin thực hiện thay vì phải nó tuyên bố tại địa phương và được truyền xung quanh trong các hàm như một tham chiếu. Bạn sẽ lý tưởng chỉ vượt qua trong các đối số cho constructor thread mà bạn cần. Việc truyền tham chiếu đến các đối tượng được khai báo trong một phạm vi ở cùng một mức "" như hàm đang được đề cập (việc thực thi luồng trong trường hợp này) thường dẫn đến các lỗi trong mã. Điều gì sẽ xảy ra nếu phạm vi trong đó mutex được khai báo là không tồn tại nữa? Liệu destructor của mutex
có làm mất hiệu lực hoạt động bên trong của mutex không? Điều gì sẽ xảy ra nếu mutex thực hiện theo cách của mình đến một mô-đun khác thông qua việc được truyền xung quanh và mô-đun đó bắt đầu chủ đề của riêng nó và nghĩ rằng mutex sẽ không bao giờ chặn, điều này có thể dẫn đến deadlocks khó chịu. Ngoài ra, một trường hợp bạn muốn sử dụng hàm tạo mutex di chuyển được nói trong một mẫu nhà máy mutex, nếu bạn muốn tạo một mutex mới, bạn sẽ thực hiện một cuộc gọi hàm và hàm đó sẽ trả về một mutex mà bạn sẽ làm sau đó thêm vào mất của bạn mutexes hoặc vượt qua để một sợi đó là yêu cầu nó thông qua một số loại dữ liệu được chia sẻ (danh sách nói trên sẽ là một ý tưởng tốt cho dữ liệu được chia sẻ này).Tuy nhiên, việc tạo mô hình nhà máy mutex như vậy có thể khá phức tạp vì bạn cần khóa quyền truy cập vào danh sách các mutex phổ biến. Nó sẽ là một điều thú vị để thử!
Nếu ý định của tác giả là tránh phạm vi toàn cầu thì hãy khai báo nó một lần trong tệp triển khai dưới dạng đối tượng tĩnh nên đủ trừu tượng.
Vâng, thông thường bạn sử dụng mutexes một cách cực kỳ cẩn thận. Khi bạn khóa một mutex, bạn muốn khóa có thời gian rất ngắn và được lựa chọn cẩn thận để bạn không gây ra bế tắc. Thông qua một tham chiếu đến khóa là một ý tưởng tồi - bạn không "sử dụng" khóa, bạn chỉ có được và sau đó bạn đưa nó trở lại. Di chuyển nó xung quanh làm cho nó khó khăn để theo dõi việc bạn sử dụng tài nguyên (quan trọng). Việc chuyển một tham chiếu đến một biến mutex thay vì khóa có thể không quá tệ, nhưng nó vẫn làm cho nó khó khăn hơn để biết những phần nào của chương trình có thể bế tắc, do đó cái gì đó cần tránh. Thông thường bạn không bao giờ cần phải làm điều đó. –
Ngoài ra nếu bạn đặc biệt đang chuyển "pthread_mutex &" vào lớp wrapper mutex của bạn, tôi có nghĩa là loại xấu xí ... cho một, bạn có thể nhận được một tham chiếu lơ lửng nếu bạn không cẩn thận, và cho hai, bạn sau đó được gắn để thực hiện pthread. Có lẽ điểm của lớp học của bạn là để che đậy các chi tiết thực hiện, nhưng ở đây bạn đang blatantly rò rỉ chúng! –
@ChrisBeck cảm ơn bạn đã cố gắng giải thích. Tôi yêu cầu bạn giải quyết vấn đề và giải pháp của nó trong "câu trả lời". –