2009-03-20 21 views
5

Cho: Tôi điền vào một loạt các xử lý với các sự kiện đặt lại tự động và chuyển nó đến WaitForMultipleObjects với bWaitAll = FALSE.Hành vi của WaitForMultipleObjects khi nhiều xử lý tín hiệu cùng một lúc

Từ MSDN: “Khi bWaitAll là FALSE, hàm này kiểm tra các chốt trong mảng theo thứ tự bắt đầu bằng chỉ mục 0, cho đến khi một trong các đối tượng được báo hiệu. Nếu nhiều đối tượng trở thành tín hiệu, hàm trả về chỉ mục của xử lý đầu tiên trong mảng có đối tượng được báo hiệu. ”

Vì vậy, bây giờ nếu nhiều đối tượng báo hiệu tôi sẽ lấy chỉ mục của giá trị đầu tiên. Tôi có phải lặp qua mảng của mình để xem liệu có bất kỳ người nào khác đã báo hiệu không?

Ngay bây giờ tôi có một vòng lặp đó là dọc theo dòng:

For (; ;) 
{ 
WaitForMultipleObjects(…) 
If (not failed) 
    Process object that called. 
    Remove the handle that signaled from the array. 
    Compact the arrary. 
} 

Trả lời

4

Vì vậy, bây giờ nếu nhiều đối tượng báo hiệu, tôi sẽ nhận được chỉ mục đầu tiên. Tôi có phải lặp lại mặc dù mảng của mình để xem liệu có bất kỳ người nào khác đã báo hiệu không?

Tại sao không chỉ quay trở lại vòng vào Wait()? nếu nhiều đối tượng được báo hiệu, chúng sẽ vẫn được báo hiệu khi bạn quay lại. Tất nhiên, nếu bạn có một đối tượng đầu tiên bắn rất nhanh trong mảng đối tượng chờ đợi, nó sẽ làm chết người khác; những gì bạn làm là đặt hàng các đối tượng của bạn trong mảng đối tượng chờ đợi theo tần suất bắn, với tần số ít nhất là đầu tiên.

BTW, nơi bạn đang sử dụng vô tận cho(), bạn có thể sử dụng goto. Nếu bạn thực sự không để lại một vòng lặp, một goto vô điều kiện đúng nhất thể hiện ý định của bạn.

+0

Đây là giải pháp hiệu quả được sử dụng. Chìa khóa tôi cần tìm ra là “nếu nhiều vật thể được báo hiệu, chúng sẽ vẫn được báo hiệu khi bạn quay trở lại.” Nếu tôi không phải lo lắng về nạn đói thì giải pháp ban đầu của tôi vẫn ổn. – Chris

+1

Có. WaitForMultipleObjects() quét mảng xử lý từ 0 trở đi và trả về ngay sau khi nó tìm thấy một xử lý được báo hiệu. Chỉ lần đầu tiên tìm thấy xử lý được đặt lại trạng thái unsignalled; những người khác bị ảnh hưởng. –

5

Yes. Một thay thế sẽ được rằng bạn có thể làm WaitForSingleObject (xử lý, 0) trên mỗi xử lý mà sẽ trở lại ngay lập tức và cho biết nếu chúng được báo hiệu hay không.

EDIT: Đây là giả mẫu cho những gì tôi có nghĩa là:

ret = WaitForMultipleObjects() 
if (ret >= WAIT_OBJECT_0 && ret < WAIT_OBJECT_0 + (count)) 
{ 
    firstSignaled = ret - WAIT_OBJECT_0; 

    // handles[firstSignaled] guaranteed signalled!! 

    for (i = firstSignaled + 1; i < count; i++) 
    { 
     if (WaitForSingleObject(handles[i], 0) == WAIT_OBJECT_0) 
     { 
      // handles[i] Signaled! 
     } 
    } 
} 
+0

Có làm được điều này sau khi WaitForMultipleObjects gọi –

+0

Cảm ơn đã gợi ý, bổ sung giả để hiển thị này. – Michael

+0

Vấn đề với câu trả lời đó là về cơ bản bạn đã bật bWaitAll với WaitForSingleObject đó. Tôi không muốn chờ đợi trên tất cả các tay cầm, chỉ cần phục vụ những người đã báo hiệu. – Chris

3

Một lựa chọn khác mà bạn có thể có là sử dụng RegisterWaitForSingleObject. Ý tưởng là bạn gắn cờ trạng thái tín hiệu của sự kiện trong mảng thứ cấp từ hàm gọi lại và sau đó báo hiệu sự kiện chính được sử dụng để đánh thức luồng chính của bạn (gọi WaitForSingleObject trên sự kiện chính).

Rõ ràng là bạn phải cẩn thận để đảm bảo rằng mảng phụ được bảo vệ khỏi truy cập bằng chuỗi chính nhưng nó sẽ hoạt động.

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