2012-03-01 34 views
8

Hệ điều hành: Windows 7Chức năng gọi cho giấc ngủ của WinAPI Sleep() dài hơn mong đợi

Khi gọi hàm WinAPI Sleep() là Ngủ (1) chủ đề thực sự ngủ trong 15ms. Tôi đã làm nó 100 lần trong một vòng lặp và tổng thời gian ngủ là 1500ms thay vì 100.

Đây có phải là hành vi phổ biến hoặc tôi nên bị lúng túng về điều gì đó sai với MOBO, CPU, cài đặt Windows?

EDIT: Nếu có thể bạn có thể chạy mã này và đăng thời gian ngủ là bao lâu. Tôi để một người bạn của tôi điều hành nó, và anh ta thực sự đã có tất cả ở 1ms.

#include <iostream> 
#include <ctime> 
#include <Windows.h> 

void test(void) 
{ 
    std::cout << "Testing 1ms sleep." << std::endl; 

    for (unsigned int i = 0; i < 10; i++) 
    { 
     std::clock_t startClocks = std::clock(); 

     Sleep(1); 

     std::clock_t clocksTaken = std::clock() - startClocks; 
     std::cout << "Time: " << clocksTaken << "ms." << std::endl; 
    } 
} 

int main(void) 
{ 
    test(); 

    std::cin.sync(); 
    std::cin.get(); 
    return 0; 
} 

EDIT2: Dường như lý do tại sao một số người đang nhận 1ms là một số chương trình khác đang chạy đặt độ phân giải bộ đếm giờ thành toàn bộ thành 1ms. Theo mặc định, điều này phải là 15,6ms trên Windows 7.

+0

Từ Giấc ngủ có thể dễ dàng mất một thời gian khác nhau tùy thuộc vào nhiều yếu tố (phần cứng/os nó đang chạy, tải của bộ vi xử lý tại thời điểm đó vv) Tôi không chắc chắn những gì bạn hy vọng đạt được bằng cách yêu cầu mọi người chạy mã đó. Nó sẽ là hoàn toàn có thể cho nó để sản xuất một thời gian khác nhau cho mỗi lần lặp của vòng lặp, mỗi lần nó chạy. – obmarg

+0

Tôi không nghĩ rằng Sleep() là phần cứng cụ thể trên Windows. Nếu bạn không chạy bất kỳ chương trình nào sử dụng timeBeginPeriod() thì kết quả sẽ là 15-16ms. Ví dụ: Windows Media Player đặt nó thành 10ms và BSPlayer thành 1ms. Nó cũng đã được nói rằng một số trình duyệt điều chỉnh nó. – NFRCR

+0

Có lẽ nó không được kết nối trực tiếp, nhưng vẫn có thể có một liên kết gián tiếp - nếu bạn đang chạy các cửa sổ trên một máy tính không đủ mạnh tải sẽ tăng lên và thời gian trước khi trở về giấc ngủ cũng có thể. – obmarg

Trả lời

7

là hành vi phổ biến này

Đó là.

Trình lập lịch trình chuỗi của cửa sổ hoạt động trên một lượng tử thời gian (độ dài chính xác phụ thuộc vào các yếu tố khác nhau bao gồm phiên bản Windows và ấn bản). Hiệu quả bất kỳ độ trễ khác không được làm tròn lên đến một lượng tử hoàn chỉnh.

+0

@MatteoItalia Một giấc ngủ bằng không sẽ ngay lập tức trở lại nếu không có gì khác có sẵn để chạy (ở mức ưu tiên này hoặc cao hơn): nó có thể không chặn chút nào. Với một giá trị khác không, như tôi đã hiểu, sẽ luôn có một số chặn. – Richard

+0

chính xác, xóa. –

0

(gỡ lỗi hoặc xây dựng bản phát hành?)

Bạn đo độ trễ như thế nào? bạn đang sử dụng một phương pháp chính xác? (queryperformancecounter)

Tôi không nghĩ bạn nên dựa vào hệ điều hành Windows để có thời gian chính xác; nó không phải là một hệ điều hành thời gian thực, và sẽ có "lực lượng" bên ngoài sẽ lấy cắp thời gian từ quá trình của bạn.

11

Chế độ ngủ có thể khiến cho chủ đề ngủ lâu hơn thời gian chờ đã chỉ định, nó chỉ đảm bảo rằng luồng sẽ ngủ ít nhất khoảng thời gian đó.

Từ documentation:

Sau khoảng thời gian ngủ đã trôi qua, các chủ đề đã sẵn sàng để chạy. Nếu bạn chỉ định 0 mili giây, chuỗi sẽ từ bỏ phần còn lại của lát thời gian của nó nhưng vẫn sẵn sàng. Lưu ý rằng một chuỗi đã sẵn sàng không được đảm bảo để chạy ngay lập tức. Do đó, luồng có thể không chạy cho đến một thời gian sau khi khoảng thời gian ngủ trôi qua. Để biết thêm thông tin, xem Scheduling Priorities.

1

Đây là hành vi khá bình thường, như hầu hết các nghị quyết đồng hồ khoảng 10-15 ms. Vì vậy, nếu bạn gọi nó với một giá trị nhỏ hơn độ phân giải đồng hồ (trong trường hợp của bạn, 1), nó có thể sẽ phải chờ ít nhất cho một chu kỳ đồng hồ, đó là lý do tại sao nó ngủ lâu hơn bạn muốn.

Nói chung, bạn không nên sử dụng chế độ Ngủ cho những thứ đòi hỏi độ chính xác như vậy do những vấn đề này.

2

Các bài viết hay nhất tôi đã tìm thấy liên quan đến thời gian trên Windows là herehere. Phần hữu ích là khi bạn thay đổi độ phân giải hẹn giờ đa phương tiện (ví dụ: timeBeginPeriod(1) trong 1ms), nó cũng ảnh hưởng đến lệnh Ngủ vì nó ảnh hưởng đến trình lên lịch nói chung. Điều này nói rằng, đạt được độ chính xác 1ms là không khả thi trên một hệ điều hành không thời gian thực.

1

Hành vi là OK. Phần cứng nằm bên dưới, phiên bản hệ điều hành và thậm chí là phần mềm chạy đang ảnh hưởng đến thói quen của hệ điều hành đối với hàm sleep().

Nếu một giấc ngủ được gọi bằng dwMilliseconds nhỏ hơn thời gian ngắt hệ thống, cuộc gọi sẽ trở lại lúc ngắt tiếp theo. Bằng cách này, sự chậm trễ thực sự phụ thuộc vào thời gian mà giấc ngủ được gọi (liên quan đến khoảng thời gian ngắt).

Bạn nên sử dụng giao diện hẹn giờ đa phương tiện để tăng tần số ngắt tới mức tối đa được phần cứng hỗ trợ, khi muốn có giấc ngủ (1).

Một cái nhìn tổng quan chi tiết về giấc ngủ() chức năng, chức năng hẹn giờ waitable, nghị quyết hẹn giờ, và các thiết lập hẹn giờ đa phương tiện có thể được tìm thấy tại Windows Timestamp Project

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