2012-02-06 34 views
8

Tôi liên tục đọc từ tập tin được ánh xạ bộ nhớ mà quy trình khác đang viết và sử dụng một mutex để đồng bộ hóa thao tác này. Trong vài thử nghiệm của tôi cho đến nay điều này hoạt động tốt, nhưng ... nếu ứng dụng của tôi bị treo ngay sau khi có được mutex và trước khi phát hành nó thì sao? Có cách nào để đảm bảo một bản phát hành của mutex, ngay cả trong trường hợp của một vụ tai nạn như vậy?Xử lý "An toàn" của Mutex?

Ngoài ra làm cách nào để xử lý sự cố của quá trình khác, có thể chưa phát hành mutex? Tôi có cần xử lý AbandonedMutexException mỗi khi tôi gọi mutex.WaitOne()?

Ngay bây giờ tôi đang làm nó tương tự như sau:

public MyState GetState() 
{ 
    MyState state = new State(); 
    this._mutex.WaitOne(); 
    try 
    { 
     state.X = this._mmView.ReadSingle(0); 
     state.Y = this._mmView.ReadSingle(4); 
     [..] 
    } 
    finally 
    { 
     this._mutex.ReleaseMutex(); 
    } 
    return state; 
} 

_mmView là một MemoryMappedViewAccessor tôi instantiated trước. Toàn bộ phương thức này GetState() được gọi là mỗi khung hình như là một phần của vòng lặp trò chơi, do đó, cứ mỗi vài phần nghìn giây.

PS: Ngoài ra, có bất kỳ vấn đề rõ ràng nào khác tại sao điều này có thể không thành công, mà tôi chưa đề cập đến?

Trả lời

11

câu trả lời Eugen là đúng - hệ điều hành sẽ phát hành các mutex cho bạn. Bây giờ hãy suy nghĩ kỹ về hậu quả của thực tế này là:

  • Bạn đã tắt mutex để đảm bảo không ai thay đổi trạng thái khi bạn đang đọc hoặc đọc trạng thái khi bạn đang tắt tiếng. Giả sử sau.
  • Ứng dụng khác muốn đọc trạng thái, vì vậy, nó sẽ cố gắng thực hiện mutex. Nó buộc phải chờ đợi.
  • Bạn đã tắt tiếng một số trạng thái và sau đó bị lỗi.
  • Hệ điều hành đã phát hành mutex.
  • Ứng dụng khác ngay lập tức mua lại mutex, và hiện đang đọc trạng thái hiệu quả "trong khi" một quá trình khác đang biến đổi nó. Thực tế là quá trình khác bây giờ đã chết và biến mất có nghĩa là trạng thái không có thật bây giờ sẽ là mãi mãi, và quá trình đọc có thể sẽ sụp đổ và chết một cách khủng khiếp. Bạn vừa đánh bại hệ thống an toàn được cung cấp bởi mutex.

Tóm lại, bạn đang lo lắng về chính xác điều sai. Bạn không nên lo lắng về điều gì sẽ xảy ra nếu mutex của tôi không bao giờ được giải phóng. Điều tồi tệ nhất xảy ra sau đó là tất cả mọi người chờ đợi mãi mãi, đó là buồn, nhưng cuối cùng người dùng sẽ khởi động lại máy. Bạn nên lo lắng về việc điều gì sẽ xảy ra nếu mutex thực hiện được giải phóng vì tôi đã bị gián đoạn giữa đột biến. Trong trường hợp đó, các quy trình giờ đây có thể sẽ bị lỗi ở khắp nơi và dữ liệu của người dùng sẽ bị hỏng vĩnh viễn.

Đừng vào tình huống đó ngay từ đầu.Giải pháp cho vấn đề là không sụp đổ khi bạn đã thực hiện một mutex để viết. Nếu bạn không viết các chương trình sụp đổ thì bạn không phải lo lắng về nó, bởi vì nó sẽ không xảy ra. Vì vậy, chỉ cần không viết chương trình mà bao giờ sụp đổ.

+3

"không viết chương trình đã từng gặp sự cố", hoặc, như thiền sư nói - "Tránh lỗi". Lời khuyên tuyệt vời. ahem. – mickeyf

+1

Tuy nhiên, âm thanh không mạnh mẽ và không thực tế. Điều gì xảy ra nếu người dùng chỉ đơn giản là giết quá trình thông qua trình quản lý tác vụ, buộc phải làm hỏng ứng dụng? – Mario

+7

@Mario: Tôi không biết bạn nghĩ gì là không thực tế; Tôi đảm bảo với bạn rằng các loại lỗi tham nhũng dữ liệu này thường xuyên bị xáo trộn và phải được bảo vệ chống lại nếu bạn quan tâm đến trạng thái dữ liệu của người dùng. Re: nếu người dùng gặp sự cố ứng dụng thì sao? Bạn đang hỏi tôi điều gì xảy ra khi người dùng thực hiện công cụ làm hỏng dữ liệu của riêng họ? ** Dữ liệu của họ bị hỏng **, đó là những gì. Người dùng không muốn dữ liệu của họ bị hỏng ** không nên gỡ xuống ứng dụng của họ **. Có một lý do * tại sao làm như vậy đặt lên một hộp thoại nói rằng "bạn có thể làm hỏng dữ liệu của bạn nếu bạn làm điều này". –

2

Khi quá trình kết thúc khi sở hữu một mutex, hệ điều hành sẽ tự động phát hành mutex cho bạn. Hãy thử điều này bằng cách yêu cầu mutex và sau đó raise new WhateverException() - quy trình khác sẽ tiếp tục.

Điều này cũng đúng cho tất cả nguyên thủy đồng bộ AFAIK

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