2010-07-05 21 views
6

Các tác động của việc gọi CloseHandle nhiều hơn một lần là gì?Có an toàn khi "đóng đôi" một tay cầm bằng CloseHandle không?

Các tài liệu nói "bạn không nên" nhưng tôi nghĩ rằng tôi có một trường hợp thực tế với các đường ống được đặt tên nơi tay cầm có thể bị đóng bên ngoài (Xem phần cuối của bài đăng).

CloseHandle ném ngoại lệ trong chế độ gỡ lỗi trong trường hợp này, điều này gợi ý cho tôi rằng các nhà phát triển nghĩ rằng điều này là nghiêm trọng, nhưng tài liệu không rõ ràng.

(Yêu cầu lịch sự: Vui lòng tránh câu trả lời "không được!" :-). Tất nhiên người ta nên tránh đóng một handke nhiều hơn một lần, và tất nhiên có những kỹ thuật tốt để giúp với điều này: Tôi chỉ quan tâm đến những gì sẽ xảy ra nếu bạn không).

Tôi đã nghe một số người đề nghị rằng nếu xử lý nhanh chóng được sử dụng lại bởi hệ điều hành, bạn có thể sẽ đóng một lệnh xử lý khác.

Điều này có khả năng không?

Windows chọn ID xử lý như thế nào?

Có bất kỳ sự đảm bảo nào về mức độ thường xuyên mà giá trị xử lý sẽ được sử dụng lại không?

(ví dụ: TCP đảm bảo rằng không thể sử dụng lại số cổng trong một khung thời gian nhất định).

Bạn có thể đóng chốt xử lý các loại xử lý không? Ví dụ: tôi có thể nghĩ rằng tôi đang đóng một đường ống nhưng cuối cùng sẽ đóng một sự kiện?

Cảm ơn!

John

(Bối cảnh thế này:. Tôi sử dụng ống có tên trong một khách hàng mô hình/máy chủ Dường như với tôi rất khó khăn để đảm bảo rằng đúng một bên được đảm bảo để đóng xử lý, ví dụ như trong quá trình sụp đổ/Có lẽ tôi sai, nhưng chắc chắn mã mẫu MSDN có vẻ như trong tâm trí của tôi để cho phép khách hàng đóng xử lý được chia sẻ, và sau đó khi máy chủ cố gắng đóng nó, nó đã bị đóng).

+0

Bạn đang đề cập đến "xử lý được chia sẻ" nào? Mỗi quá trình cần được tạo * và * đóng chốt điều khiển của chính nó vào cùng một đường ống. Làm thế nào để xử lý kết thúc việc chia sẻ? Than ôi, câu trả lời ** là ** "chỉ là không", nhưng đó là bởi vì xử lý không nên được chia sẻ ở tất cả. – shambulator

Trả lời

11

đủ đơn giản để kiểm tra:

HANDLE h = 0; 
h = CreateMutex(NULL, TRUE, NULL); 
printf("%X\n", h); 
CloseHandle(h); 
h = 0; 
h = CreateMutex(NULL, TRUE, NULL); 
printf("%X\n", h); 

Trong x64 WinXP của tôi này sản xuất:

2E8 
2E8 

Vì vậy, có bạn có nó.
Không giống như các cổng TCP, các chốt xử lý được tái chế ngay lập tức.

Lặp lại thử nghiệm này với API yêu thích của bạn hoặc bất kỳ kết hợp nào của chúng.

+0

+1, Ngoài ra một tay cầm có thể được tái sử dụng cho các đối tượng của bất kỳ loại - có thể mutex, có thể cái gì khác. Làm CloseHandle() hai lần có thể có những hậu quả đáng ngạc nhiên. – sharptooth

4

Bạn có thể có hình ảnh tinh thần sai về một đường ống. Nó có hai đầu, mỗi đầu được thể hiện bằng một số khác nhau xử lý. Có, CloseHandle phải được gọi hai lần để làm cho trường hợp ống biến mất. Nhưng vì chúng là các tay cầm khác nhau, điều đó không bao giờ có thể gây ra bất kỳ vấn đề nào. Cũng lưu ý rằng các cá thể xử lý là quá trình cụ thể. Ngay cả khi chúng có cùng giá trị trong cả hai quá trình, chúng không tham chiếu cùng điểm cuối của đường ống.

+0

Hmm có lẽ tôi đã hiểu lầm. Nhưng tôi đã chắc chắn nhìn thấy vấn đề mà khách hàng để đường ống đóng ống, và máy chủ sau đó ném một ngoại lệ "xử lý không hợp lệ" (trong chế độ gỡ lỗi). – John

1

Có hai điều có thể xảy ra:

  1. Bạn đóng một tay cầm mở bởi một số mã khác.Điều đó có thể không ảnh hưởng đến mã của bạn nhưng nó có thể là thảm họa cho mã khác.
  2. Nếu bạn đang chạy với một trình sửa lỗi được đính kèm, bạn làm hỏng ứng dụng của bạn vì hệ điều hành sẽ tăng ngoại lệ khi phát hiện một chốt xử lý không hợp lệ bị đóng.

Không có IMHO nào hấp dẫn đặc biệt.