睡眠数毫秒


630

我知道POSIX sleep(x)函数会使程序休眠x秒。在C ++中是否有使程序休眠x 毫秒的功能?


7
您应该知道,无论如何在Windows中Sleep()都具有毫秒级的精度,但是其精度可能高出几个数量级。你可能会认为你的睡眠4毫秒,但实际上睡400
约翰Dibling

5
@John Dibling:我认为他正在使用POSIX sleep,而不是在Sleep给定“ x秒” 的情况下使用win32 。
CB Bailey 2010年

1
尽管C和C ++具有不同的名称修饰,这可能是错误和不兼容的来源,但在大多数情况下,在C ++中使用C标头是可以的。但是,如果要绝对确定没有问题,请#includeextern "C" {}块内使用C标头。另外,如果您在同一项目中拥有C和C ++源文件,则强烈建议您这样做以避免出现任何问题,尤其是在两种源文件中都包含相同的头文件的情况下(在这种情况下,这是必要的) 。如果您有一个纯C ++项目,它可能完全没有问题。
adam10603

2
@JohnDibling不,不是400ms。您可能曾经获得过的最差精度是Windows 9x,其GetTickCount分辨率为55ms。更高版本的分辨率为16ms或更小。一位用户以为他从“睡眠”中获得了16ms的分辨率,但随后报告说它Sleep本身是相当准确的,并且明显的不精确性是由于GetTickCount用来测量时间的流逝而引起的。
Qwertie

Answers:


457

请注意,毫秒级没有标准的C API,因此(在Unix上)您必须满足usleep,它接受微秒:

#include <unistd.h>

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

2
忙着睡觉吗?我需要在睡眠时屈服于另一个线程;我可以用usleep吗?
迈克尔

13
这不是一个忙碌的等待stackoverflow.com/a/8156644/1206499nanosleep因为usleep它已经过时了,所以可能是一个更好的选择。
jswetzen 2015年

4
尼特,请考虑提及@ HighCommander4的答案,如果您使用的是C ++ 11编译器,则答案更易于移植。
einpoklum 2016年

6
usleep()在POSIX中于2001年弃用,并在2008
。– Jetski S型

1269

在C ++ 11中,可以使用标准库工具来执行此操作:

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

清晰易读,无需再猜测sleep()功能所采用的单位。


6
std :: this_thread :: sleep_for是否定义中断点?像boost :: this_thread_sleep一样吗?
Martin Meeser

73
这是正确的方法。期。线程是跨平台的,也是计时的。
Void

88
@虚空 当然,这是一个很好的方法,但是“ the”和“ period”是非常强烈的用词。
疯狂物理学家,2015年

5
忙着睡觉吗?我需要在睡眠时屈服于另一个线程;我可以用sleep_for吗?
迈克尔

14
@迈克尔:这不是一个忙碌的睡眠,它会屈服于其他线程。
HighCommander4

83

为了保持便携性,您可以使用Boost :: Thread进行睡眠:

#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;
}

该答案是重复的,之前已在此问题中发布。也许您也可以在那里找到一些可用的答案。


6
请记住,在多线程环境中,boost::this_thread::sleep会在代码中添加中断点。boost.org/doc/libs/1_49_0/doc/html/thread/...
马丁Meeser


33

根据您的平台,您可能拥有usleepnanosleep可用。usleep不推荐使用,并且已从最新的POSIX标准中删除;nanosleep是首选。


6
注意,虽然在/中usleep()声明了while <unistd.h>,但令人困惑。nanosleep()<time.h><ctime>
gbmhunter 2014年

27

为什么不使用time.h库?在Windows和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;
}

更正的代码-现在,CPU保持空闲状态[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
该代码的问题之一是它是一个繁忙的循环,它将继续使用100%的单个处理器内核。睡眠功能是围绕OS调用实现的,它将使当前线程进入睡眠状态并执行其他操作,并且仅在指定时间到期时才会唤醒线程。
伊斯梅尔2014年

没错-它会消耗一个CPU内核的100%。因此,这里是使用系统睡眠功能重写的代码-并且它仍然是跨平台的:
Bart Grzybicki 2014年

@BartGrzybicki我知道这是一个古老的答案,但在Windows机器上的Visual Studio 2017中,#ifdef WIN32默认情况下不会评估为true。
kayleeFrye_onDeck

2
@kayleeFrye_onDeck代码错误。应该是#ifdef _WIN32
康坦戈

1
@Contango我知道!但是当我写的时候不是...大声笑。感谢您的跟进!
kayleeFrye_onDeck

17

nanosleepusleep- 相比,它是更好的选择-它对中断更具弹性。


6
我熟悉usleep但不熟悉nanosleep。您应该提供在Linux上使用它的示例。
jww

14
#include <windows.h>

句法:

Sleep (  __in DWORD dwMilliseconds   );

用法:

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

3
您需要为此包括什么?
2014年

#include <WinBase.h>
foob​​ar 2014年

7
不,您需要#include <windows.h>
2014年

7
这个问题强烈暗示需要POSIX解决方案。
Toby Speight

7

如果使用MS Visual C ++ 10.0,则可以使用标准库工具执行此操作:

Concurrency::wait(milliseconds);

你会需要:

#include <concrt.h>

10
当您实际上不是真正的意思时,请不要使用“标准”一词。 <concrt.h>不是一个标准库头-这可能是一个平台库; 在这种情况下,您应该清楚说明先决条件。
Toby Speight

5

在具有该select功能的平台(POSIX,Linux和Windows)上,您可以执行以下操作:

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.
    }
}

但是,当今有更好的替代方法。


似乎无法在Windows计算机上的VS2017中编译:error LNK2019: unresolved external symbol _select@20 referenced in function "void __cdecl sleep(unsigned long)" (?sleep@@YAXK@Z)
kayleeFrye_onDeck

@kayleeFrye_onDeck确实可以编译。只是不链接。查找Windows文档。
Maxim Egorushkin

您为timeval使用什么标题?
Totte Karlsson

4

用C ++休眠程序的Sleep(int)方法就是该方法。它的头文件是#include "windows.h."

例如:

#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;
}

它的睡眠时间以毫秒为单位,没有限制。

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

3
您是什么意思呢?它的限制一定是0xFFFFFFFE。等待0xFFFFFFFF不会超时(这意味着它将等待直到程序结束)。
Izzy 2015年

我不是那个像Izzy那样的人,对不起我们的误会。我的意思是您可以输入任何正数毫秒。因此它将等待许多毫秒关闭程序。如果您不明白,请这样说,我将向您进一步解释。
2015年

是的,但是实际时间分辨率是多少?在某些情况下是15-16毫秒吗?例如,如果您使用Sleep(3),它将实际睡眠3毫秒还是改为15-16毫秒?
彼得·莫滕森

3

选择呼叫是一种更精确的方法(可以以纳秒为单位指定睡眠时间)。


尽管这可能是解决问题的宝贵提示,但好的答案也可以证明解决方案。请编辑以提供示例代码以显示您的意思。或者,考虑将其写为注释。
Toby Speight

3

使用Boost异步输入/输出线程,睡眠x毫秒;

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

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

如果您尝试睡眠3毫秒,实际上会发生什么?会改为15-16毫秒吗?你测量了吗?
彼得·莫滕森

1

这个问题很老,但是我设法找到了一种简单的方法可以在我的应用程序中使用。您可以创建一个C / C ++宏,如下所示使用它:

#ifndef MACROS_H
#define MACROS_H

#include <unistd.h>

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

#endif // MACROS_H


0

作为POSIX系统的Win32替代品:

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

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

宁愿nanosleep()usleep():后者已被弃用,已经从最近的POSIX标准中删除。
Toby Speight
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.