Ngủ trong một phần nghìn giây


631

Tôi biết sleep(x)chức năng POSIX làm cho chương trình ngủ trong x giây. Có một chức năng để làm cho chương trình ngủ trong x mili giây trong C ++ không?


7
Bạn nên lưu ý rằng, dù sao trong Windows, Sleep()độ chính xác đến một phần nghìn giây , nhưng độ chính xác của nó có thể là các đơn đặt hàng có cường độ cao hơn. Bạn có thể nghĩ rằng bạn ngủ trong 4 mili giây, nhưng thực sự ngủ trong 400.
John Dibling

5
@ John Dibling: Tôi nghĩ rằng anh ấy đang sử dụng POSIX sleep, chứ không phải win32 Sleepvới "x giây".
CB Bailey

1
Mặc dù C và C ++ có cách xáo trộn tên khác nhau, có thể là nguồn gây ra lỗi và không tương thích, nhưng trong hầu hết các trường hợp, sử dụng tiêu đề C trong C ++ là tốt. Tuy nhiên, nếu bạn muốn hoàn toàn chắc chắn rằng không có gì sai, #includetiêu đề C bên trong một extern "C" {}khối. Ngoài ra, nếu bạn có các tệp nguồn C và C ++ trong cùng một dự án, chúng tôi khuyên bạn nên làm điều này để tránh mọi vấn đề, đặc biệt là nếu bạn bao gồm các tiêu đề giống nhau trong cả hai loại tệp nguồn (trong trường hợp này là cần thiết) . Nếu bạn có một dự án hoàn toàn C ++, nó có thể không hoạt động mà không có vấn đề gì cả.
adam10603

2
@ JohnDibling không, không phải 400ms. Độ chính xác tồi tệ nhất bạn có thể nhận được là từ Windows 9x, có GetTickCountđộ phân giải 55ms; các phiên bản sau có độ phân giải 16ms trở xuống. Một người dùng nghĩ rằng anh ta nhận được độ phân giải 16ms từ chế độ Ngủ nhưng sau đó báo cáo rằng Sleepbản thân nó khá chính xác và sự thiếu chính xác rõ ràng là do sử dụng GetTickCountđể đo thời gian trôi qua.
Qwertie

Câu trả lời:


457

Lưu ý rằng không có API C tiêu chuẩn cho mili giây, vì vậy (trên Unix) bạn sẽ phải giải quyết usleep, chấp nhận micro giây:

#include <unistd.h>

unsigned int microseconds;
...
usleep(microseconds);

2
Có phải là một giấc ngủ bận rộn? Tôi cần nhường cho một chủ đề khác trong khi ngủ; Tôi có thể sử dụng usleepcho điều đó?
Michael

13
Đây không phải là một ngăn xếp chờ đợi bận rộn.com/a/ 8156644/1206499 , và nanosleepcó thể là một lựa chọn tốt hơn vì usleepđã lỗi thời.
jswetzen

4
Niet, vui lòng xem xét đề cập đến câu trả lời của @ HighCommander4 dễ mang theo hơn nếu bạn có trình biên dịch C ++ 11.
einpoklum

6
us ngủ () không dùng nữa trong POSIX năm 2001 và bị xóa vào năm 2008
Jetski S-type

1270

Trong C ++ 11, bạn có thể làm điều này với các cơ sở thư viện tiêu chuẩn:

#include <chrono>
#include <thread>
std::this_thread::sleep_for(std::chrono::milliseconds(x));

Rõ ràng và có thể đọc được, không cần phải đoán đơn vị nào mà sleep()hàm thực hiện.


6
Std :: this_thread :: ngủ_for có xác định điểm gián đoạn không? Giống như boost :: this_thread_s ngủ nào?
Martin Meeser

73
Đây là cách đúng đắn để làm điều đó. Giai đoạn = Stage. Chủ đề là nền tảng chéo cũng như chrono.
Vô hiệu

88
@Void. Một cách rất tốt chắc chắn, nhưng "thời kỳ" và "thời kỳ" là những từ cực kỳ mạnh mẽ.
Nhà vật lý điên

5
Có phải là một giấc ngủ bận rộn? Tôi cần nhường cho một chủ đề khác trong khi ngủ; Tôi có thể sử dụng sleep_forcho điều đó?
Michael

14
@Michael: Đây không phải là một giấc ngủ bận rộn, nó sẽ mang lại những chủ đề khác.
HighCommander4

83

Để luôn di động, bạn có thể sử dụng Boost :: Thread để ngủ:

#include <boost/thread/thread.hpp>

int main()
{
    //waits 2 seconds
    boost::this_thread::sleep( boost::posix_time::seconds(1) );
    boost::this_thread::sleep( boost::posix_time::milliseconds(1000) );

    return 0;
}

Câu trả lời này là một bản sao và đã được đăng trong câu hỏi này trước đây. Có lẽ bạn có thể tìm thấy một số câu trả lời có thể sử dụng ở đó quá.


6
Hãy nhớ rằng - trong một môi trường đa luồng - boost::this_thread::sleepthêm một điểm gián đoạn vào mã của bạn. boost.org/doc/libs/1_49_0/doc/html/thread/ triệt
Martin Meeser

35

Trong Unix bạn có thể sử dụng us ngủ .

Trong Windows có chế độ Ngủ .


4
và cuộc gọi Windows tính bằng mili giây.
shindigo

17
Bạn phải bao gồm <unistd.h> hoặc <Windows.h> tương ứng.
gbmhunter

Có, nhưng không thể độ phân giải thời gian thực tế là 15-16 ms (ngay cả khi đơn vị trong cuộc gọi là 1 ms) và do đó thời gian tối thiểu là 15-16 ms?
Peter Mortensen

33

Tùy thuộc vào nền tảng của bạn, bạn có thể có usleephoặc nanosleepcó sẵn. usleepkhông được chấp nhận và đã bị xóa khỏi tiêu chuẩn POSIX gần đây nhất; nanosleepđược ưa thích.


6
Lưu ý rằng trong khi usleep()được khai báo <unistd.h>, khó hiểu, nanosleep()được khai báo trong <time.h>/ <ctime>.
gbmhunter

27

Tại sao không sử dụng thư viện time.h? Chạy trên hệ thống Windows và POSIX:

#include <iostream>
#include <time.h>

using namespace std;

void sleepcp(int milliseconds);

void sleepcp(int milliseconds) // Cross-platform sleep function
{
    clock_t time_end;
    time_end = clock() + milliseconds * CLOCKS_PER_SEC/1000;
    while (clock() < time_end)
    {
    }
}
int main()
{
    cout << "Hi! At the count to 3, I'll die! :)" << endl;
    sleepcp(3000);
    cout << "urrrrggghhhh!" << endl;
}

Mã đã sửa - hiện CPU vẫn ở trạng thái IDLE [2014.05.24]:

#include <iostream>
#ifdef _WIN32
    #include <windows.h>
#else
    #include <unistd.h>
#endif // _WIN32

using namespace std;

void sleepcp(int milliseconds);

void sleepcp(int milliseconds) // Cross-platform sleep function
{
    #ifdef _WIN32
        Sleep(milliseconds);
    #else
        usleep(milliseconds * 1000);
    #endif // _WIN32
}
int main()
{
    cout << "Hi! At the count to 3, I'll die! :)" << endl;
    sleepcp(3000);
    cout << "urrrrggghhhh!" << endl;
}

24
Một trong những vấn đề với mã đó là nó là một vòng lặp bận rộn, nó sẽ tiếp tục sử dụng 100% lõi xử lý đơn. Chức năng ngủ được triển khai xung quanh một cuộc gọi hệ điều hành sẽ đưa vào chế độ ngủ của luồng hiện tại và thực hiện một thao tác khác và chỉ đánh thức luồng khi hết thời gian đã chỉ định.
Ismael

Bạn nói đúng - nó sẽ tiêu thụ 100% một lõi CPU. Vì vậy, đây là mã được viết lại bằng cách sử dụng các chức năng ngủ của hệ thống - và nó vẫn là nền tảng chéo:
Bart Grzybicki

@BartGrzybicki tôi biết đây là một câu trả lời cũ, nhưng trong Visual Studio 2017 trên máy tính windows, #ifdef WIN32không được đánh giá là đúng theo mặc định.
kayleeFrye_onDeck

2
@kayleeFrye_onDeck Mã sai. Nó phải #ifdef _WIN32.
Contango

1
@Contango Tôi biết điều đó! Nhưng không phải khi tôi viết nó ... lol. Cảm ơn đã theo lên!
kayleeFrye_onDeck

17

nanosleeplà một lựa chọn tốt hơn usleep- nó kiên cường hơn trước các ngắt.


6
Tôi đã quen thuộc usleep, nhưng không nanosleep. Bạn nên cung cấp một ví dụ về việc sử dụng nó trên Linux.
jww

14
#include <windows.h>

Cú pháp:

Sleep (  __in DWORD dwMilliseconds   );

Sử dụng:

Sleep (1000); //Sleeps for 1000 ms or 1 sec

3
Bạn cần bao gồm những gì cho điều này?
ʇolɐǝz qoq

#include <WinBase.h>
foobar

7
Không, bạn cần phải#include <windows.h>
olɐǝz qoq

7
Câu hỏi ngụ ý mạnh mẽ rằng một giải pháp POSIX là bắt buộc.
Toby Speight

7

Nếu sử dụng MS Visual C ++ 10.0, bạn có thể thực hiện việc này với các tiện ích thư viện tiêu chuẩn:

Concurrency::wait(milliseconds);

bạn sẽ cần:

#include <concrt.h>

10
Đừng sử dụng từ "tiêu chuẩn" khi bạn không thực sự có nghĩa như vậy. <concrt.h>không một tiêu đề thư viện chuẩn - nó có thể là một thư viện nền tảng; trong trường hợp bạn nên nêu rõ các điều kiện tiên quyết.
Toby Speight

5

Trên các nền tảng có selectchức năng (POSIX, Linux và Windows) bạn có thể làm:

void sleep(unsigned long msec) {
    timeval delay = {msec / 1000, msec % 1000 * 1000};
    int rc = ::select(0, NULL, NULL, NULL, &delay);
    if(-1 == rc) {
        // Handle signals by continuing to sleep or return immediately.
    }
}

Tuy nhiên, có những lựa chọn thay thế tốt hơn hiện nay.


Dường như không thể biên dịch trong VS2017 trên máy Windows:error LNK2019: unresolved external symbol _select@20 referenced in function "void __cdecl sleep(unsigned long)" (?sleep@@YAXK@Z)
kayleeFrye_onDeck

@kayleeFrye_onDeck Nó biên dịch. Chỉ không liên kết. Tra cứu tài liệu Windows của bạn.
Maxim Egorushkin

bạn sử dụng tiêu đề nào cho timeval ??
Totte Karlsson

@TotteKarlsson <sys/time.h>.
Maxim Egorushkin

4

Cách để ngủ chương trình của bạn trong C ++ là Sleep(int)phương pháp. Các tập tin tiêu đề cho nó là#include "windows.h."

Ví dụ:

#include "stdafx.h"
#include "windows.h"
#include "iostream"
using namespace std;

int main()
{
    int x = 6000;
    Sleep(x);
    cout << "6 seconds have passed" << endl;
    return 0;
}

Thời gian nó ngủ được đo bằng mili giây và không có giới hạn.

Second = 1000 milliseconds
Minute = 60000 milliseconds
Hour = 3600000 milliseconds

3
Bạn có nghĩa là nó không có giới hạn? Nó chắc chắn có giới hạn là 0xFFFFFFFE. Chờ đợi 0xFFFFFFFF sẽ không hết thời gian (có nghĩa là nó sẽ đợi cho đến khi chương trình kết thúc).
Izzy

Tôi không có ý như thế Izzy, xin lỗi vì sự hiểu lầm của chúng tôi. Tôi có nghĩa là bạn có thể nhập bất kỳ số mili giây tích cực. Vì vậy, nó sẽ chờ đợi nhiều mili giây để đóng chương trình. Nếu bạn không hiểu xin vui lòng nói như vậy, tôi sẽ giải thích cho bạn nhiều hơn.
Phi

Có, nhưng những gì nó giải quyết thời gian thực tế? Nó không thể là 15-16 ms trong một số trường hợp? Ví dụ, nếu bạn sử dụng Ngủ (3) thì nó thực sự sẽ ngủ trong 3 ms hay thay vào đó là 15-16 ms?
Peter Mortensen

3

Chọn cuộc gọi là cách để có độ chính xác cao hơn (thời gian ngủ có thể được chỉ định bằng nano giây).


Trong khi điều này có thể là một gợi ý có giá trị để giải quyết vấn đề, một câu trả lời tốt cũng cho thấy giải pháp. Vui lòng chỉnh sửa để cung cấp mã ví dụ để hiển thị những gì bạn có ý nghĩa. Thay vào đó, hãy xem xét viết này như là một bình luận thay thế.
Toby Speight

3

Sử dụng các luồng đầu vào / đầu ra không đồng bộ Boost, ngủ trong x mili giây;

#include <boost/thread.hpp>
#include <boost/asio.hpp>

boost::thread::sleep(boost::get_system_time() + boost::posix_time::millisec(1000));

Điều gì thực sự sẽ xảy ra nếu bạn cố gắng ngủ trong 3 mili giây? Thay vào đó sẽ là 15-16 mili giây? Bạn đã đo nó chưa?
Peter Mortensen

1

Câu hỏi đã cũ, nhưng tôi đã tìm ra một cách đơn giản để có điều này trong ứng dụng của mình. Bạn có thể tạo một macro C / C ++ như bên dưới sử dụng nó:

#ifndef MACROS_H
#define MACROS_H

#include <unistd.h>

#define msleep(X) usleep(X * 1000)

#endif // MACROS_H

1

Từ C ++ 14 bằng cách sử dụng tiêu chuẩn và cả chữ số của nó:

#include <chrono>
#include <thread>

using namespace std::chrono;

std::this_thread::sleep_for(123ms);

0

Là một thay thế Win32 cho các hệ thống POSIX:

void Sleep(unsigned int milliseconds) {
    usleep(milliseconds * 1000);
}

while (1) {
    printf(".");
    Sleep((unsigned int)(1000.0f/20.0f)); // 20 fps
}

Thích nanosleep()đến usleep(): sau này bị phản đối và đã bị xóa từ các tiêu chuẩn POSIX nhất gần đây.
Toby Speight
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.