2009-06-06 26 views
6

Có một số chủ đề trong ứng dụng của tôi hoạt động ở chế độ nền. Chúng kết nối với cơ sở dữ liệu và thực hiện một số truy vấn chọn thời gian. Trong hầu hết các trường hợp, các truy vấn này chỉ trả về một vài bản ghi. Theo thời gian, tuy nhiên, họ có thể trả lại hàng chục ngàn hồ sơ. Tất cả những điều này sau đó được xử lý trong một vòng lặp.Delphi - điều chỉnh thời gian ngủ của chủ đề

Vì tình huống như vậy có thể xảy ra trong một số chủ đề cùng một lúc, tôi không muốn ứng dụng của tôi sử dụng 100% thời gian CPU khi các luồng đó đang xử lý dữ liệu; tôi không muốn làm cho tất cả các chủ đề chiến đấu cho thời gian của bộ vi xử lý. Vì vậy, tôi gọi hàm Sleep() trong mỗi lần lặp của các vòng trong các luồng đó.

Tôi không biết, tuy nhiên, cách điều chỉnh thời gian ngủ. Tôi không muốn các vòng lặp kéo dài mãi mãi, vì vậy thời gian ngủ không thể quá dài. Tôi đặt nó đến 2 mili giây trong mỗi lần lặp (trong mỗi chủ đề) (tại sao 2ms? - đó là một câu hỏi hay :)).

Tôi nghĩ, mặt khác, tôi có thể kéo dài thời gian ngủ, nhưng chỉ gọi ngủ một lần mỗi lần lặp lại (giả sử, Ngủ (100) cứ 50 lần lặp lại). Tôi nên chọn phương pháp nào? Một vòng lặp của các vòng lặp mất khoảng 30 ms mỗi (không có bất kỳ giấc ngủ nào).

Vui lòng thông báo.

Cảm ơn!
Mariusz.

Trả lời

9

Gọi Ngủ() không có ý nghĩa. Sử dụng tất cả sức mạnh xử lý mà bạn có thể nhận được, và để cho hệ thống làm việc ra sao để lập kế hoạch tốt nhất cho các chủ đề của bạn. Gọi số Chế độ Ngủ() sẽ chỉ gây thêm các chuyển mạch ngữ cảnh và giảm thông lượng của bạn. Nếu xử lý nền ảnh hưởng đến chủ đề chính của bạn hoặc các ứng dụng khác, thì hãy giảm mức độ ưu tiên của các chủ đề nền tương ứng.

Nếu bạn muốn cho phép các chủ đề ngủ để hạn chế lượng dữ liệu mà chúng tạo ra cho người tiêu dùng, hãy xem xét hàng đợi của nhà sản xuất-người tiêu dùng. Có các nhà sản xuất chỉ đơn giản là chặn khi hàng đợi của họ là đầy đủ, theo cách này bạn sẽ không cần phải ở tất cả để fiddle với thời gian.

Cũng lưu ý rằng việc sử dụng CPU tối đa thường là một điều tốt, đặc biệt là trên các bộ vi xử lý hiện đại. Ngay cả trên máy tính xách tay có một thời gian ngắn tải cao là tốt hơn so với kéo dài nhân tạo thời gian công việc của bạn cần, như bộ vi xử lý/toàn bộ hệ thống sẽ sớm có thể nhập các trạng thái năng lượng thấp hơn.

+0

Nhưng nếu điều này chạy trên nền tảng trên một máy tính mà còn có ai đó làm việc trên (ví dụ như viết một bảng tính), bạn không muốn quá trình nền để làm cho quá trình nền trước không sử dụng được. – dummzeuch

+2

Đúng, nhưng đó là lý do tại sao tôi viết rằng ưu tiên luồng nền có thể được hạ thấp, giữ cho các ứng dụng khác (hoặc chủ đề chính) đáp ứng trong khi vẫn sử dụng toàn bộ tiềm năng hệ thống. Trên các hệ thống (đa lõi) hiện đại, việc lưu trữ tất cả các lõi được tải đầy đủ là một vấn đề lớn hơn là thiếu sự đáp ứng của ứng dụng nền trước. Và I/O không được tối ưu hóa lớn là một mối đe dọa lớn hơn nhiều đối với khả năng sử dụng của một hệ thống hơn là tải CPU cao. – mghie

2

Có thể có các cách tiếp cận tốt hơn so với sử dụng giấc ngủ để kiểm soát chủ đề của bạn. Vì cuộc gọi cơ sở dữ liệu của bạn có thể trả về 1-1000 bản ghi để xử lý, có thể có ý nghĩa khi tách ứng dụng của bạn thành hai lớp, có thể sử dụng hàng đợi thông điệp để đệm các yêu cầu. Ứng dụng của bạn có thể gọi đến dịch vụ dữ liệu và sau đó dịch vụ dữ liệu sẽ chạy truy vấn và gửi các thông điệp dữ liệu riêng lẻ (hoặc khối thông điệp, v.v.) tới hàng đợi. Sau đó, ứng dụng của bạn có thể tạo bao nhiêu chủ đề phù hợp để xử lý thư. Thêm chủ đề có nghĩa là xử lý nhanh hơn với chi phí của CPU, nhưng bạn có thể điều chỉnh điều này để có được số dư phù hợp.

3

Bạn chỉ nên tạo chuỗi ưu tiên thấp và để chúng hoạt động mà không ngủ, nếu không bạn không sử dụng toàn bộ sức mạnh của CPU. Ví dụ trên hệ thống đa lõi/đa CPU. Hoặc nếu hệ thống của bạn là 100% nhàn rỗi: tại sao chờ hoặc ngủ?

Nhưng nếu bạn cần một số giấc ngủ, hãy lưu ý rằng giấc ngủ (1) đợi 10-15ms (!) Vì thời gian Windows mặc định. Bạn có thể sử dụng timeBeginPeriod (1) của đơn vị MMSystem.pas để đặt độ phân giải thành 1ms :-) (tôi đã sử dụng điều này cho giao tiếp nối tiếp).

0

sử dụng TThread.Sleep() từ System.Classes, thay vì Sleep() từ WinApi.Cửa sổ

// Winapi.Windows contains GetTickCount and Sleep 
// System.Classes contains TThread (universal option) // TThread.GetTickCount() // TThread.Sleep() 
uses System.Types, System.Classes, Vcl.Forms; 

// sau đó trong quá trình bạn sử dụng sau đây

TThread.Sleep(0); 

Application.ProcessMessages(); // clear all Vcl messages // part of Vcl.Forms 
CheckSynchronize(); // check all threaded events 
Các vấn đề liên quan