Tôi có một lớp có trạng thái (một enum đơn giản) và được truy cập từ hai luồng. Để thay đổi trạng thái, tôi sử dụng một mutex (boost :: mutex). Có an toàn để kiểm tra trạng thái (ví dụ: so sánh state_ == ESTABLISHED) hoặc tôi có phải sử dụng mutex trong trường hợp này không? Nói cách khác, tôi cần mutex khi tôi chỉ muốn đọc một biến mà có thể được đồng thời được viết bởi một thread?Tôi có cần một mutex để đọc không?
Trả lời
Có. Nếu chủ đề đọc một biến trong khi luồng b đang ghi vào nó, bạn có thể đọc một giá trị không xác định. Thao tác đọc và ghi không phải là nguyên tử, đặc biệt là trên một hệ thống đa bộ xử lý.
Nói chung bạn không, nếu biến của bạn được khai báo là "dễ bay hơi". Và CHỈ nếu nó là một biến duy nhất - nếu không bạn nên thực sự cẩn thận về các chủng tộc có thể.
Tại sao bạn nghĩ các vấn đề dễ bay hơi? – jalf
@jalf: volatile yêu cầu trình biên dịch không thực hiện tối ưu hóa có thể làm cho mã của bạn nhìn thấy một bản sao cũ của biến. –
Nhưng câu hỏi không phải là về các bản sao cũ. Ngay cả khi biến không phải là biến động, nó sẽ được viết ra sớm hay muộn. Nó sẽ là nguyên tử bất kể biến động, và dễ bay hơi không ngăn cản tải/lưu trữ sắp xếp lại. Vì vậy, dễ bay hơi không thực sự mua cho bạn bất cứ điều gì trong trường hợp này. Nó không giải quyết được vấn đề cần giải quyết, và nó giải quyết một vấn đề đã được giải quyết. – jalf
Cần bảo vệ quyền truy cập vào enum (đọc hoặc ghi).
Một điều khác: Nếu tranh chấp chủ đề ít hơn và các chủ đề thuộc cùng một quá trình thì phần quan trọng sẽ tốt hơn mutex.
Bạn có hai chủ đề, họ trao đổi thông tin, có bạn cần một mutex và bạn cũng có thể cần phải chờ đợi có điều kiện.
Trong ví dụ của bạn (so sánh state_ == ESTABLISHED) cho biết luồng # 2 đang chờ thread # 1 để khởi tạo kết nối/trạng thái. Không có mutex hoặc điều kiện/sự kiện, luồng # 2 phải thăm dò trạng thái liên tục.
Chủ đề được sử dụng để tăng hiệu suất (hoặc cải thiện khả năng phản hồi), bỏ phiếu thường dẫn đến hiệu suất giảm, hoặc bằng cách tiêu thụ rất nhiều CPU hoặc bằng cách giới thiệu latencey do khoảng thời gian thăm dò ý kiến.
+1 để đề xuất các biến có điều kiện. Từ những âm thanh của nó, anh ta có một sợi chỉ cần phản ứng với sự thay đổi trạng thái bởi một sự thay đổi khác. Nếu đó là trường hợp các biến điều kiện thì thích hợp hơn nhiều. – Falaina
@Ermelli chúng ta vẫn cần mutex nếu chúng ta muốn sử dụng vòng lặp chờ đợi bận rộn (vì vòng lặp có thể làm điều gì đó khác) – Nick
thực sự, không có lý do gì để khóa truy cập đối tượng để đọc. bạn chỉ muốn khóa nó khi viết cho nó. điều này chính là điều mà một khóa người đọc viết là. nó không khóa đối tượng miễn là không có hoạt động ghi. nó cải thiện hiệu suất và ngăn ngừa deadlocks. xem các liên kết sau đây để giải thích phức tạp hơn:
Nó phụ thuộc.
Ngôn ngữ C++ không nói gì về chủ đề hoặc nguyên tử.
Nhưng trên nhất CPU hiện đại, đọc số nguyên là hoạt động nguyên tử, có nghĩa là bạn sẽ luôn đọc giá trị nhất quán, ngay cả khi không có mutex.
Tuy nhiên, không có mutex hoặc một số hình thức đồng bộ hóa khác, trình biên dịch và CPU được tự do sắp xếp lại lần đọc và viết, vẫn không an toàn trong trường hợp chung.
Giả sử chuỗi nhà văn cập nhật một số dữ liệu, sau đó đặt cờ nguyên để thông báo cho các luồng khác có dữ liệu, có thể sắp xếp lại để cờ được đặt trước khi cập nhật dữ liệu. Trừ khi bạn sử dụng mutex hoặc một hình thức rào cản bộ nhớ khác.
Vì vậy, nếu bạn muốn hành vi chính xác, bạn không cần một mutex như vậy, và nó không có vấn đề nếu một thread ghi vào biến trong khi bạn đang đọc nó. Nó sẽ là nguyên tử trừ khi bạn đang làm việc trên một CPU rất bất thường.Nhưng bạn do cần một rào cản bộ nhớ của một số loại để ngăn chặn sắp xếp lại trong trình biên dịch hoặc CPU.
Trừ khi bạn chỉ định biến động đọc (hoặc ghi) có thể * không bao giờ * được thực hiện. Sớm hay muộn thì không đủ tốt. – EFraim
Nhưng ngay cả với biến động, CPU hoặc trình biên dịch có thể sắp xếp lại các bài viết, làm cho chúng vô nghĩa. Giải pháp chính xác là một rào cản bộ nhớ, và sau đó dễ bay hơi chỉ là một sự mất quyền lực không cần thiết. – jalf
@ jalf: Không, nếu bạn chỉ cần một lá cờ duy nhất. Đọc lại câu hỏi. – EFraim
- 1. Tôi có nên vứt bỏ Mutex không?
- 2. Tôi có cần khóa danh sách STL với mutex trong kịch bản push_back pop_front không?
- 3. hiện một chức năng getter cần một mutex?
- 4. Sitecore không có quyền cần thiết để đọc/tạo quầy
- 5. Phát hành một Mutex
- 6. boost :: mutex :: ~ mutex(): Xác nhận `! Pthread_mutex_destroy (& m) 'không thành công
- 7. Tôi có thực sự cần libgcc không?
- 8. Tôi có cần Vứt bỏ() hoặc Đóng() một EventWaitHandle không?
- 9. jQuery - Tôi có cần URL mã hóa một biến không?
- 10. boost :: mutex/Làm thế nào để kiểm tra nếu một mutex bị khóa
- 11. Làm thế nào tôi có thể lập trình tạo, đọc, viết một excel mà không cần cài đặt văn phòng?
- 12. Xóa một mutex từ một quá trình
- 13. Tôi có cần bao gồm @synthesize không?
- 14. tôi có cần đóng std :: fstream không?
- 15. Tôi có cần một máy Mac để tạo một gói ứng dụng Java không?
- 16. Tôi có cần mèo để viết một heredoc vào một tập tin không?
- 17. Tôi có cần làm StreamWriter.flush() không?
- 18. C# - làm cách nào tôi có thể lấy tên của chủ sở hữu cho một Mutex
- 19. Đọc từ mongodb mà không cần khóa
- 20. Tôi có cần khóa ở đây không?
- 21. Tôi có cần đặt lại luồng (C#) về đầu không?
- 22. Tôi có cần gọi Close() trên ManualResetEvent không?
- 23. Có thể khởi tạo tĩnh các mutex trong Windows không?
- 24. Mutexes có cần thiết trong javascript không?
- 25. Biến điều kiện vẫn cần một mutex nếu bạn thay đổi giá trị được kiểm tra một cách nguyên tử?
- 26. Có một webservice hoặc API để giúp tôi đọc địa chỉ liên lạc email không?
- 27. Tôi có thể lấy một tệp socket.makefile để có cùng ngữ nghĩa đọc như một tệp thông thường không?
- 28. Không std :: mutex tạo ra một hàng rào?
- 29. Có cách nào tôi có thể làm hai lần đọc nguyên tử không?
- 30. Tại sao khóa một std :: mutex không chặn thread
trong khi chuỗi ghi (fetch-> write-> store) Tôi không thấy khi nào ở giữa những người đọc sẽ tìm nạp giá trị không xác định, hoặc giá trị trước đó, nhưng không bao giờ được xác định. –
Tính các giá trị enum tài khoản được đọc trong một hướng dẫn. –
@Arkaitz: không xác định có lẽ không phải là từ đúng. Nhưng các kiến trúc CPU/bộ nhớ ngày càng trở nên phức tạp với các mức cache bổ sung, độ trễ tăng lên vv Câu trả lời rất đơn giản: Nói Không! để chia sẻ dữ liệu không bị khóa. Ngay cả các chuyên gia cũng phạm nhiều sai lầm trong lĩnh vực này. – sellibitze