2009-03-07 23 views
6

này:thể một SetEvent đơn() kích hoạt nhiều WaitForSingleObject()

http://msdn.microsoft.com/en-us/library/ms686915(VS.85).aspx

dường như cho thấy không.

Tôi có ba quy trình giao tiếp qua đường ống. Quy trình A Tạo một sự kiện, Quy trình B & C mỗi lần sử dụng WaitForSingleObject (trong chuỗi thứ hai).

Vì vậy, bây giờ chúng tôi có các quy trình -TWO- mỗi quá trình chờ sự kiện -SINGLE.

Quy trình A kích hoạt sự kiện với SetEvent(), Quy trình B phản hồi, quy trình C không.

Kết luận:

Mỗi WaitForSingleObject() yêu cầu sự kiện duy nhất ... đúng không?

Trả lời

5

Sử dụng các sự kiện đặt lại thủ công để kích hoạt nhiều chuỗi của một sự kiện.

Here là một ví dụ trong đó sử dụng "Sổ tay Thiết lập lại tổ chức sự kiện" cờ

+0

Đáng tiếc là tôi không kiểm soát được quy trình A vì vậy tôi không thể thực hiện điều đó. –

2

Bạn có thể sử dụng Evenets Thiết lập lại bằng tay và chức năng PulseEvent để giải phóng tất cả các chủ đề hiện chờ đợi sự kiện này.

Tuy nhiên, lưu ý rằng cách tiếp cận này vốn đã có tính ưu việt, vì không có cách nào để biết đó là "chuỗi hiện đang chờ ...". Bạn nên sử dụng cơ chế đồng bộ đáng tin cậy hơn nếu cần khớp chính xác các sự kiện chờ wakeup/2.

+0

Tôi đã không đề cập đến điều này, nhưng tôi không có bất kỳ kiểm soát quá trình A, nhưng tôi sẽ xem xét các chức năng PulseEvent để tham khảo trong tương lai .. cảm ơn. –

+0

Nếu bạn chỉ có thể thay đổi chủ đề B & C, tốt nhất là nên đánh một sợi từ chủ đề khác (ví dụ: A -> B -> C) thay vì cố đánh thức tất cả các chủ đề từ A. BTW, nếu bạn không control A, bạn nên có một số giao thức/giao thức khóa/wakeup, và đề cập đến điều này trong câu hỏi. – jpalecek

+1

Không sử dụng PulseEvent, xem http://blogs.msdn.com/oldnewthing/archive/2005/01/05/346888.aspx – CesarB

0

Tôi hy vọng ví dụ này có thể giúp bạn:

handle1A = CreateEvent(LPSECURITY_ATTRIBUTES, ManualReset, InitialState, NAME) 

handle1B = CreateEvent(LPSECURITY_ATTRIBUTES, ManualReset, InitialState, NAME) 

handle2A = CreateEvent(LPSECURITY_ATTRIBUTES, ManualReset, InitialState, NAME+GetCurrentThreadId()) 

handle2B = CreateEvent(LPSECURITY_ATTRIBUTES, ManualReset, InitialState, NAME+GetCurrentThreadId()) 

A) nếu bạn tạo một sự kiện với cùng NAME, mỗi setEvent hiệu tất cả waitforsingleobjects

SetEvent(handle1A) // Send signaling to handle1A and handle1B 

B) nếu bạn tạo một sự kiện với duy nhất, setEvent chỉ gửi tín hiệu đến tay cầm được tham chiếu

SetEvent(handle2) // Send signling only to handle2A. The Id Thread is unique 
0

Một sự kiện có thể thông báo cho nhiều chủ đề nếu đó là sự kiện đặt lại thủ công. Sự kiện tự động đặt lại không thể thực hiện điều đó. Nếu nhiều hơn một tread đang chờ đồng thời cho một sự kiện tự động thiết lập lại, và bạn đặt nó vào trạng thái được báo hiệu, chỉ có một luồng tồn tại và reset nó, và hành vi của các luồng khác sẽ không được xác định. Mặc dù, từ tài liệu của Microsoft, chúng tôi có thể giả định rằng một và chỉ một luồng sẽ thoát trong khi những người khác chắc chắn sẽ không thoát. Dù sao, chúng ta phải đưa ra các báo sau đây để xem xét: “Đừng cho rằng lệnh đầu tiên, đầu tiên (FIFO). Các sự kiện bên ngoài như APC chế độ hạt nhân có thể thay đổi thứ tự chờ ”Nguồn - https://msdn.microsoft.com/en-us/library/windows/desktop/ms682655(v=vs.85).aspx

Chức năng CreateEvent có tham số bManualReset. Nếu nó là TRUE, hàm tạo đối tượng sự kiện thủ công đặt lại, yêu cầu sử dụng hàm ResetEvent để đặt trạng thái sự kiện thành không có tín hiệu. Nếu tham số này là FALSE, hàm sẽ tạo đối tượng sự kiện tự động đặt lại và hệ thống sẽ tự động đặt lại trạng thái sự kiện thành không được báo hiệu sau khi một chuỗi chờ duy nhất đã được giải phóng, tức là đã thoát khỏi một hàm như WaitForMultipleObjects hoặc WaitForSigleObject - nhưng, Tôi đã viết trước đó, chỉ có một chủ đề sẽ được thông báo không phải tất cả.

Như về PulseEvent - đó là không đáng tin cậy và không bao giờ nên được sử dụng - xem https://msdn.microsoft.com/en-us/library/windows/desktop/ms684914(v=vs.85).aspx

Chỉ những chủ đề sẽ được thông báo bởi PulseEvent rằng đang ở trong "chờ" nhà nước tại thời điểm PulseEvent được gọi. Nếu họ đang ở trong bất kỳ tiểu bang khác, họ sẽ không được thông báo, và bạn có thể không bao giờ biết chắc chắn về trạng thái của luồng. Một chủ đề chờ đợi trên một đối tượng đồng bộ hóa có thể được loại bỏ trong giây lát khỏi trạng thái chờ bằng một chế độ hạt nhân Gọi không đồng bộ thủ tục, và sau đó trở về trạng thái chờ sau khi APC hoàn tất. Nếu cuộc gọi đến PulseEvent xảy ra trong thời gian khi luồng đã được gỡ bỏ khỏi trạng thái đợi, luồng sẽ không được giải phóng vì PulseEvent chỉ phát hành những luồng đang đợi tại thời điểm nó được gọi. Bạn có thể tìm hiểu thêm về các kernel-mode Asynchronous Thủ tục Calls (APC) tại các liên kết sau đây:

Bạn có thể lấy ý tưởng thêm về auto đặt lại sự kiện và các sự kiện đặt lại thủ công từ bài viết sau:

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