2010-12-01 34 views
6

Tôi đã đọc một vài nguồn về phương pháp thích hợp để sủi bọt một tin nhắn từ một chuỗi đến tất cả các chủ đề khác để thoát ra một cách duyên dáng (mỗi luồng thực hiện quy trình thoát riêng của nó). Trong số này, tôi thích ý tưởng của một boolean nguyên tử toàn cầu có thể được gắn cờ từ bất kỳ luồng nào, và tất cả các luồng khác kiểm tra cờ này để thực hiện một thường trình thoát - khi tất cả các luồng được nối, luồng chính có thể thoát khỏi ứng dụng.Thoát hiệu quả từ ứng dụng đa luồng (chi tiết cụ thể)

Chủ đề tính toán hoàn toàn có thể sẽ được xử lý khác nhau, đúng không?

Tính năng này có hiệu quả và an toàn không? Có cách nào tốt hơn để làm điều này?

Cảm ơn!

Trả lời

1

Trong Windows, tôi sử dụng QueueUserAPC để gọi một hàm có thể đưa ra một ngoại lệ, làm cho các luồng thoát khỏi sạch.

tôi đã viết thêm về các chi tiết trong câu trả lời này ở đây:

How do I guarantee fast shutdown of my win32 app?

Nói tóm lại, đây là những gì sẽ xảy ra:

Say thread muốn chấm dứt thread B (và sau đó C, D, ...)

  • Chủ đề A gọi QueueUserAPC(), chuyển núm điều khiển đến chuỗi B và địa chỉ của hàm sẽ loại trừ ngoại lệ của lớp của tôi ThreadExit.
  • Chủ đề B chạy bình thường cho đến khi nó gọi điều gì đó kiểm tra thời gian chờ cảnh báo. Có thể WaitForSingleObjectEx, có thể là SleepEx hoặc thứ khác.
  • Tại thời điểm này, luồng B chạy chức năng APC được truyền trước đó, khiến cho ngoại lệ được ném vào Chủ đề B.
  • Tất cả các đối tượng được phân bổ sẽ tự động bị hủy chính xác vì ngoại lệ làm cho luồng B 'thư giãn'.
  • Hàm thread ngoài cùng của luồng B sẽ bắt ngoại lệ.
  • Chủ đề B hiện đang thoát, có thể báo hiệu cho Chủ đề A đã hoàn tất.
+0

âm thanh thông minh, nhưng tôi chỉ không thể lắc "này là cách quá hacky" cảm giác mỗi khi tôi đọc nó ... – Necrolis

+0

Tôi sẽ thừa nhận nó không di động, nhưng hầu hết các giải pháp khác thực sự hạn chế những gì bên thứ ba mã bạn có thể sử dụng trong chuỗi của mình. Tôi sử dụng chủ đề rất nhiều cho mạng, và cần thư viện mạng của bên thứ ba (ví dụ, Indy) có thể được 'dừng' một cách an toàn. – Roddy

+0

Tôi vẫn không hiểu được, ngay cả từ lời giải thích chi tiết hơn. Bạn sử dụng QueueUserAPC khi bạn muốn thoát khỏi bên trong một chủ đề và điều này cuối cùng gọi một chức năng mà ném một ngoại lệ và ngoại lệ này đạt đến tất cả các chủ đề? Các destructors được gọi như thế nào và hàm ngoại lệ ném như thế nào? (Toàn bộ khu vực lập trình này là mới đối với tôi) Cảm ơn! – oneminute

4

Tôi không phải là chủ nhân của các chủ đề kiểm tra biến trạng thái boolean (hoặc khác) để biết khi nào nên làm gì, bởi vì nó lãng phí. Các chủ đề sẽ phải quay, liên tục kiểm tra biến để xem có hướng dẫn mới hay không. Điều này làm bỏng CPU.

Một tùy chọn tốt hơn là tạo một semaphore hoặc trong Windows một sự kiện và có tất cả các chủ đề chờ đợi trên đó. Các chủ đề có thể ngủ trong khi họ không bận rộn, và sẽ không đánh cắp các lát thời gian từ các chủ đề khác làm công việc thực sự đơn giản chỉ để kiểm tra một biến.

+0

(Tôi mới đến lý thuyết song song) Ứng dụng của tôi là dành riêng cho Windows - Các chủ đề chờ một sự kiện như thế nào? Bất kỳ tài nguyên nào bạn có thể chỉ cho tôi? – oneminute

+0

Trong Windows, bạn sẽ sử dụng nhóm chức năng WaitForSingleObject() để đợi một sự kiện được tạo bởi CreateEvent(). Liên kết: http://msdn.microsoft.com/en-us/library/ms682396(VS.85).aspx –

+0

Tôi hơi bối rối .. vì vậy trong mỗi chủ đề tôi kiểm tra sự trở lại của WaitForSingleObject (exitHandle, 0) để xem sự kiện thoát có được báo hiệu không? – oneminute

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