2010-08-14 25 views
8

Tôi đã có một chương trình NET đơn giản, mà sẽ kiểm tra xem trường hợp khác đã được bắt đầu:.NET Mutex trên nền tảng Windows: Điều gì sẽ xảy ra với họ sau khi tôi hoàn thành?

Mutex mutex = new Mutex(false,"MyMutexName"); 
    if (!mutex.WaitOne(1)) 
     return; 

    try{ 
    //do stuff 
    } 
    catch{ //exceptions} 
    finally 
    { 
     mutex.ReleaseMutex(); 
    } 

Câu hỏi của tôi là, những gì chính xác xảy ra với mutex nếu bạn quên để phát hành nó khi chương trình kết thúc ? Nó có thể nhìn thấy trong một số thành phần bảng điều khiển cửa sổ? Nó sống ở đâu?

+0

Các mutex được đặt tên thường chỉ được sử dụng để điều phối liên lạc chéo, không phải ví dụ của bạn hiển thị. –

+0

@Steven: Sử dụng mutexes cho việc này là một cách sử dụng thực sự tốt. Tốt hơn là cố gắng để phát hiện một cửa sổ trước đó hoặc tên quá trình hoặc một cái gì đó. – erikkallen

+0

Tôi đã cập nhật câu hỏi của mình, vì bạn đang thực hiện hai điều liên quan đến bán trong mã của mình: 1) Sử dụng mutex được đặt tên để phát hiện sự tồn tại của phiên bản trước của ứng dụng của bạn 2) Đồng bộ hóa giữa các quá trình với mutex đó. –

Trả lời

11

Đây là một mutex được đặt tên để nó có thể nhìn thấy và có thể được mở trong các quy trình khác. Windows sử dụng một số tham chiếu đơn giản trên tay cầm. Nếu bạn không Dispose() nó một cách rõ ràng chính mình sau đó finalizer sẽ đóng xử lý cho bạn. Nếu chương trình của bạn đánh bom mạnh và không bao giờ thực thi trình hoàn thiện thì Windows sẽ làm điều đó khi nó dọn sạch các tài nguyên được chương trình của bạn sử dụng.

Điều đó sẽ tự động giảm số lượng tham chiếu. Nếu điều đó đếm ngược về 0 (không có quá trình nào khác có một chốt xử lý mở trên nó) thì đối tượng hạt nhân được giải phóng.

Nói cách khác: bạn không gặp vấn đề gì cho dù mọi thứ trở nên tồi tệ đến mức nào. Đối tượng đột biến thực sự sống trong nhóm bộ nhớ hạt nhân. Bạn có thể xem nó bằng công cụ WinObj của SysInternals.

+0

Phải, đây là những gì tôi đã nói ban đầu về xử lý. Các biến chứng ở đây là, nếu một quá trình khác được xử lý để mutex được đặt tên của bạn, và sau đó bạn tắt một sợi sau khi có được quyền sở hữu, mutex bị bỏ qua. Xem câu trả lời của tôi để biết thêm chi tiết. –

+0

Ngoài ra, Mutex.Dispose() không phát hành nó. Cần gọi ReleaseMutex() một cách rõ ràng, nếu không chủ sở hữu mới sẽ nhận được AbandonedMutexException. –

2

Mutexes là các nút điều khiển cấp hệ điều hành. Họ sẽ nhận được đóng lại khi quá trình của bạn không (nếu bạn không đóng chúng sớm hơn, đó là.)

chỉnh sửa

Ok, tôi hiểu lầm rõ ràng ví dụ câu hỏi. Nếu bạn chỉ đang cố gắng phát hiện liệu một cá thể khác có tồn tại hay không, bạn sẽ tạo một mutex có tên (hoặc đối tượng tương tự) và chỉ cần kiểm tra sự tồn tại của nó mà không bao giờ khóa nó.

Gọi tới WaitOne khóa trên đó, lấy quyền sở hữu, trong khi ReleaseMutex loại bỏ nó (miễn là không có cuộc gọi bổ sung nào tới WaitOne). Nếu bạn kết thúc chủ đề mà không phát hành đầy đủ mutex, nó không để đối tượng ở trạng thái xấu, như được giải thích trong trích dẫn văn bản Micah.

Tôi đã đặt câu hỏi của bạn là về việc bạn đóng xử lý trước khi quá trình hoàn tất, đó là một điều hoàn toàn khác.

thêm

Tại SDK [API] [1] cấp độ, bạn có thể gọi CreateMutex với kỳ vọng của thất bại khi một mutex cùng tên đã được tạo ra. Trong .NET (tốt, trong 4.0, ít nhất), có một [hàm tạo] [2] điền vào một bool createdNew.

[1]: http://msdn.microsoft.com/en-us/library/ms682411(VS.85).aspx CreateMutex

[2]: http://msdn.microsoft.com/en-us/library/bwe34f1k(v=VS.90).aspx Mutex

2

Từ MSDN

Nếu một thread chấm dứt khi sở hữu một mutex , mutex được cho là bị bỏ rơi . Trạng thái của mutex là được đặt thành tín hiệu và chuỗi chờ đợi tiếp theo là được quyền sở hữu. Nếu không có ai sở hữu mutex, trạng thái của mutex là được báo hiệu. Bắt đầu từ phiên bản 2.0 của Khuôn khổ .NET, một Ngoại lệ AbandonedMutex được đưa ra trong chuỗi tiếp theo sẽ nhận được cú pháp . Trước phiên bản 2.0 của khung công tác .NET, không có ngoại lệ nào được ném .

Thận trọng

Một mutex bị bỏ rơi thường chỉ ra một lỗi nghiêm trọng trong các mã. Khi thoát luồng mà không cần giải phóng đột biến , cấu trúc dữ liệu được bảo vệ bởi mutex có thể không ở trạng thái nhất quán .Các chủ đề tiếp theo để yêu cầu quyền sở hữu của mutex có thể xử lý ngoại lệ này và tiếp tục, nếu tính toàn vẹn của cấu trúc dữ liệu có thể được xác minh.

Trong trường hợp của một mutex toàn hệ thống, một mutex bị bỏ rơi có thể chỉ ra rằng một ứng dụng đã bị chấm dứt đột ngột (ví dụ, bằng cách sử dụng Windows Task Manager).

+2

Để làm rõ, điều gì tạo ra một mutex "toàn hệ thống" là nhiều quá trình có một xử lý với nó. Nếu không, khi quá trình đóng, nó sẽ mất mutex với nó. –

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