2012-06-26 35 views
22

Trong C++ 11, chức năng timeout *_until chỉ hoạt động như mong đợi nếu đồng hồ ổn định (tức là một đồng hồ chỉ di chuyển về phía trước với tốc độ không thay đổi) được sử dụng. Bởi vì system_clock không phải là một chiếc đồng hồ ổn định, đó có nghĩa là mã như thế này có thể cư xử khá ngạc nhiên:Khi nào nó thích hợp để sử dụng hàm C++ 11 * _until timeout thay vì hàm * _for tương ứng?

using namespace std::chrono; 
std::this_thread::sleep_until(system_clock::now() + seconds(10)); 

này sẽ làm cho thread hiện hành vào giấc ngủ trong vòng 10 giây trừ khi đồng hồ hệ thống được điều chỉnh trong thời gian ngủ, ví dụ như, cho thời gian tiết kiệm ánh sáng ban ngày. Nếu đồng hồ được đặt trở lại một giờ trong khi ngủ, luồng hiện tại sẽ ngủ trong một giờ và 10 giây.

Từ những gì tôi có thể biết, mỗi hàm thời gian chờ *_until trong C++ 11 có chức năng *_for tương ứng mất một khoảng thời gian thay vì một dấu thời gian. Ví dụ, đoạn code trên có thể được viết lại như sau:

using namespace std::chrono; 
std::this_thread::sleep_for(seconds(10)); 

Các *_for chức năng không cần phải lo lắng về đồng hồ mà có được điều chỉnh trong khi hàm được thực hiện, bởi vì họ chỉ nói bao lâu để chờ đợi, không phải những gì thời gian nó được cho là khi thời gian chờ kết thúc.

Sự cố này ảnh hưởng nhiều đến các chức năng ngủ, vì điều này cũng đúng cho thời gian chờ dựa trên thời gian chờ và các chức năng try_lock.

Tình hình duy nhất mà tôi có thể hình dung nó làm cho cảm giác sử dụng một chức năng *_until với một đồng hồ không ổn định sẽ là khi bạn muốn để có những điều chỉnh đồng hồ vào tài khoản, ví dụ, bạn muốn ngủ cho đến thứ tư tới tại 3: 30 giờ sáng, ngay cả khi có thay đổi hoặc từ giờ tiết kiệm ánh sáng ban ngày từ nay đến giờ. Có các tình huống khác trong đó các chức năng *_until có ý nghĩa hơn các chức năng *_for không? Nếu không, có an toàn khi nói rằng, nói chung, chức năng thời gian chờ *_for có nên được ưu tiên hơn các chức năng *_until không?

+0

Điều đó có phụ thuộc vào _steadiness_ của _clock_ không? «Wait_for' và' wait_until' có thực sự có ý định hoạt động khác trong việc xử lý 'nhảy đồng hồ' không? –

+0

@ K-ballo: Đúng vậy, đó là lý do tại sao tôi đề cập cụ thể sự ổn định của đồng hồ và system_clock không ổn định. Các hàm '_for' và' _until' hoạt động khác nhau liên quan đến điều chỉnh đồng hồ, nhưng những gì _intention_ không rõ ràng với tôi. – KnowItAllWannabe

+1

_steadiness_ của 'system_clock' thực sự phụ thuộc vào việc triển khai thực hiện. –

Trả lời

9

Số gọi xxx_until khi bạn có thời hạn. Các trường hợp sử dụng điển hình là nơi bạn có một giới hạn thời gian khó khăn cho một phần của mã mà có chứa nhiều chờ đợi, hoặc nơi mà thời gian tiêu thụ của mỗi bước trước khi chờ đợi là không thể đoán trước.

ví dụ:

void foo() { 
    std::chrono::steady_clock::time_point const timeout= 
    std::chrono::steady_clock::now()+std::chrono::milliseconds(30); 

    do_something_which_takes_some_time(); 

    if(some_future.wait_until(timeout)==std::future_status::ready) 
    do_something_with(some_future.get()); 
} 

này sẽ chỉ xử lý các giá trị từ some_future nếu nó đã sẵn sàng trong vòng 30ms từ đầu, bao gồm cả thời gian thực hiện cho do_something_which_takes_some_time().

Như trong ví dụ này, hầu hết các trường hợp sử dụng của các hàm xxx_until sẽ sử dụng đồng hồ ổn định để có thời gian chờ có thể dự đoán được.

Trường hợp duy nhất mà tôi có thể tưởng tượng bằng cách sử dụng xxx_until chức năng với một chiếc đồng hồ không ổn định (ví dụ như std::chrono::system_clock) là nơi mà thời gian chờ là người dùng có thể nhìn thấy, và phụ thuộc vào giá trị của đồng hồ lựa chọn. Đồng hồ báo thức hoặc chương trình nhắc nhở là một ví dụ, một chương trình sao lưu chạy "lúc nửa đêm" là một chương trình khác.

4

Một trường hợp sử dụng cho chức năng sleep_until là nếu bạn muốn ngủ cho đến một thời điểm cụ thể và không phải là thời lượng cụ thể. Ví dụ, nếu bạn có một chuỗi chỉ được kích hoạt lúc 3 giờ chiều mỗi ngày, bạn phải tính toán thời lượng (bao gồm xử lý tiết kiệm ánh sáng ban ngày và năm nhuận) để sử dụng với sleep_for hoặc bạn có thể sử dụng sleep_until.

+1

Đồng hồ báo thức là một ví dụ tuyệt vời về điều gì đó cần tính đến Giờ tiết kiệm ánh sáng ban ngày. Giờ làm việc của bạn được điều chỉnh theo DST và do đó bạn nên sử dụng đồng hồ báo thức của mình. –

2

Sử dụng tốt cho sleep_until là trong các vòng lặp thời gian ổn định (như vòng trò chơi). Nếu bạn không chắc chắn sẽ mất bao lâu để xử lý, nhưng nó phải thường là có độ dài tối thiểu nhất định, bạn có thể tăng thời gian chờ để chu kỳ thời gian cho đến chu kỳ. Ví dụ:

// requires C++14 
#include <iostream> 
#include <thread> 
#include <chrono> 

using namespace std; 
using namespace std::chrono; 
using namespace std::literals; 

int main() 
{ 
    auto start_time = steady_clock::now(); 

    for (auto i = start_time; i <= start_time + 1s; i += 50ms) { 
    this_thread::sleep_until(i); 
    cout << "processing cycle..." << endl; 
    } 

    return 0; 
} 

Nhưng sau đó bạn đã có thể có để theo dõi các sự chậm chạp khi một chu kỳ mất còn hơn thời gian tăng.

Ý tưởng là, nếu bạn ngây thơ sleep_for, bạn sẽ ngủ trong khoảng thời gian chu kỳ thời gian cần để chạy mã trong vòng lặp của mình.

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