Trước hết, tôi vẫn tự làm quen với đa luồng, và không biết nhiều thuật ngữ. Tôi cần phải chắc chắn rằng tôi đang làm điều này đúng, bởi vì nó là một chủ đề nhạy cảm.Quản lý số chủ đề động
Thông số kỹ thuật
Những gì tôi đang xây dựng là một thành phần trong đó sẽ chứa một số năng động của chủ đề. Mỗi chủ đề này được sử dụng lại để thực hiện một số yêu cầu. Tôi có thể cung cấp tất cả các chi tiết cần thiết cho chủ đề khi tạo và trước khi thực thi nó, cũng như cung cấp trình xử lý sự kiện. Một khi nó được thực hiện, tôi thực hiện khá nhiều với một yêu cầu, và tôi ăn trong một yêu cầu khác. Các yêu cầu đang được đưa vào các chủ đề này từ một chuỗi nền độc lập khác liên tục xử lý một hàng đợi các yêu cầu. Vì vậy, hệ thống này có hai danh sách: 1) Danh sách các hồ sơ yêu cầu, và 2) Danh sách các con trỏ thread.
Tôi đang sử dụng con cháu của lớp TThread
(ít nhất đây là phương pháp luồng mà tôi quen thuộc). Tôi nhận được phản hồi từ các chủ đề bằng cách đồng bộ hóa trình kích hoạt sự kiện mà tôi đã chỉ định khi tạo chuỗi. Các chủ đề đang tải và lưu dữ liệu ở chế độ nền và khi chúng hoàn tất, chúng sẽ tự thiết lập lại để xử lý yêu cầu tiếp theo.
Vấn đề
Bây giờ những rắc rối bắt đầu khi quyết định làm thế nào để xử lý các trường hợp thay đổi số lượng các đề cho phép (thông qua một tài sản của các thành phần ActiveThreads: TActiveThreadRange
mà TActiveThreadRange
= 1..20). Do đó, có thể có bất cứ nơi nào giữa 1 và 20 chủ đề được tạo ra tại một thời điểm. Nhưng khi, giả sử, ứng dụng sử dụng thành phần này sẽ thay đổi thuộc tính này từ 5 thành 3. Lúc này, đã có 5 luồng được tạo và tôi không muốn buộc luồng đó miễn phí nếu nó bận. Tôi cần phải chờ cho đến khi nó được thực hiện trước khi tôi giải phóng nó. Và mặt khác, nếu thuộc tính được thay đổi từ 3 đến 5, thì tôi cần phải tạo 2 luồng mới. Tôi cần phải biết cách tiếp cận thích hợp để 'theo dõi' các chủ đề này trong kịch bản này.
khả năng
Dưới đây là một số cách có thể tôi có thể nghĩ ra để 'theo dõi' những chủ đề ...
- Giữ một
TList
chứa mỗi thread tạo - dễ dàng quản lý - Tạo một bao bọc
TList
hoặc hậu duệ chứa mỗi chuỗi được tạo - dễ quản lý hơn, nhưng nhiều công việc hơn - Giữ
array
contai ning mỗi thread được tạo ra - Điều này có tốt hơn mộtTList
không? - Tạo một wrapper mảng chứa mỗi thread tạo
Nhưng sau đó trở lại vấn đề ban đầu của tôi - Phải làm gì với chủ đề bận rộn hiện khi tài sản ActiveThreads
được giảm? Tạo chúng không có vấn đề gì, nhưng việc giải phóng chúng đang trở nên khó hiểu. Tôi thường tạo ra các chủ đề tự giải phóng, nhưng đây là lần đầu tiên tôi tạo ra một cái được tái sử dụng. Tôi chỉ cần biết phương pháp thích hợp để phá hủy những chủ đề này mà không làm gián đoạn nhiệm vụ của họ.
Cập nhật
Dựa trên những phản hồi, tôi đã mua và bắt đầu thực hiện OmniThreadLibrary (cũng như FastMM dài cần thiết). Tôi cũng đã thay đổi cách tiếp cận của tôi một chút - Một cách mà tôi có thể tạo ra các quy trình luồng mà không quản lý họ và không có một thread để xử lý hàng đợi ...
- 1 phương pháp tổng thể để đẻ trứng một quá trình mới
function NewProcess(const Request: TProcessRequest): TProcessInfo;
TProcessRequest
là một kỷ lục với thông số kỹ thuật của những gì cần phải làm (Tên file, tùy chọn, vv)TProcessInfo
là một kỷ lục mà họ sẽ trả lại một số thông tin trạng thái.
- Cấp dữ liệu trong trình xử lý sự kiện cho trường hợp được 'thực hiện' với nhiệm vụ khi tạo quy trình mới. Khi thành phần nhận được thông báo này, nó sẽ kiểm tra hàng đợi.
- Nếu lệnh được xếp hàng đợi, nó sẽ so sánh quá trình giới hạn hoạt động với quá trình hiện đếm
- > Nếu vượt quá giới hạn, chỉ cần dừng lại và quá trình tiếp theo hoàn thành sẽ làm thực hiện cùng một séc
- > Nếu trong giới hạn, Kick off khác quy trình mới (sau khi đảm bảo quá trình trước đó được thực hiện)
- Nếu không có lệnh đang xếp hàng đợi, sau đó chỉ dừng lại
- Mỗi quá trình có thể chết ngày của riêng mình sau khi đã thực hiện nhiệm vụ của mình (không có luồng giữ-sống)
- tôi sẽ không phải lo lắng về timer khác hoặc sợi liên tục lặp qua
- Thay vì mỗi quá trình phá hủy tự và kiểm tra nó cho các yêu cầu mới trước khi làm như vậy
Cập nhật Một
Tôi đã thực sự hoàn nguyên về sử dụng TThread
vì OTL rất khó sử dụng. Tôi thích giữ những thứ được bọc và tổ chức trong lớp riêng của nó.
Điều bạn đang hỏi về được gọi là "nhóm chủ đề"; có lẽ điều đó sẽ giúp bạn tìm tài nguyên. –
Xem [delphi-threaded-list-of-thread-jobs-queueing] (http://stackoverflow.com/questions/1805633/delphi-threaded-list-of-thread-jobs-queueing). Và đừng cuộn hồ bơi chủ đề của riêng bạn, hãy xem [OTL-OmniThreadLibrary] (http://code.google.com/p/omnithreadlibrary/). –
Trải nghiệm cá nhân của tôi là dễ dàng hơn khi làm việc với Windows API trực tiếp thay vì dựa vào 'TThread' nếu bạn đang thực hiện một số công việc phức tạp hơn. Thực tế, rất dễ dàng để bắt đầu luồng bằng cách sử dụng API Windows. Bắt đầu bằng cách thực hiện các thí nghiệm đơn giản với ['CreateThread'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453 (v = vs.85) .aspx). Chỉ cần cẩn thận rằng bạn, với tư cách là một nhà phát triển Delphi, có lẽ nên sử dụng trình bao bọc 'System.BeginThread' thay cho' CreateThread', nhưng, tất nhiên, tài liệu MSDN 'CreateThread' vẫn hợp lệ. –