นอนเป็นมิลลิวินาที


631

ฉันรู้ว่าsleep(x)ฟังก์ชั่นPOSIX ทำให้โปรแกรมนอนหลับเป็นเวลา x วินาที มีฟังก์ชั่นเพื่อทำให้โปรแกรมสลีปสำหรับ x มิลลิวินาทีใน C ++ หรือไม่


7
คุณควรทราบว่าใน Windows นั้นSleep()มีความแม่นยำเป็นมิลลิวินาทีแต่ความแม่นยำนั้นอาจมีลำดับที่สูงกว่า คุณอาจคิดว่าการนอนหลับของคุณเป็นเวลา 4 มิลลิวินาที แต่จริง ๆ แล้วนอนเพื่อ 400
จอห์น Dibling

5
@ John Dibling: ฉันคิดว่าเขาใช้ POSIX sleepไม่ใช่ win32 ที่Sleepให้ "x seconds"
CB Bailey

1
แม้ว่า C และ C ++ จะมีชื่อ mangling ที่แตกต่างกันซึ่งอาจเป็นแหล่งของข้อบกพร่องและความไม่ลงรอยกันในกรณีส่วนใหญ่มันเป็นเรื่องดีที่จะใช้ส่วนหัว C ใน C ++ อย่างไรก็ตามหากคุณต้องการแน่ใจว่าไม่มีอะไรผิดพลาด#includeส่วนหัว C ภายในextern "C" {}บล็อก นอกจากนี้หากคุณมีไฟล์ต้นฉบับ C และ C ++ ในโครงการเดียวกันขอแนะนำให้คุณทำเช่นนี้เพื่อหลีกเลี่ยงปัญหาใด ๆ โดยเฉพาะอย่างยิ่งหากคุณรวมส่วนหัวเดียวกันในไฟล์ต้นฉบับทั้งสองประเภท (ในกรณีนี้จำเป็น) . หากคุณมีโครงการ C ++ เพียงอย่างเดียวอาจเป็นไปได้ว่าจะไม่มีปัญหาเลย
adam10603

2
@ JohnDibling ไม่ไม่ใช่ 400ms ความแม่นยำที่แย่ที่สุดที่คุณเคยได้รับมาจาก Windows 9x ซึ่งGetTickCountมีความละเอียด 55ms; รุ่นที่ใหม่กว่ามีความละเอียด 16ms หรือน้อยกว่า ผู้ใช้รายหนึ่งคิดว่าเขาได้รับความละเอียด 16ms จาก Sleepแต่แล้วรายงานว่าSleepตัวเองนั้นค่อนข้างแม่นยำและความไม่แน่นอนที่ชัดเจนนั้นเกิดจากการใช้GetTickCountเพื่อวัดระยะเวลา
Qwertie

คำตอบ:


457

โปรดทราบว่าไม่มี C API มาตรฐานสำหรับมิลลิวินาทีดังนั้น (สำหรับ Unix) คุณจะต้องชำระusleepซึ่งยอมรับ microseconds:

#include <unistd.h>

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

2
เป็นการนอนที่ยุ่งหรือเปล่า? ฉันต้องยอมจำนนต่อเธรดอื่นในระหว่างการนอนหลับ; ฉันสามารถใช้usleepสิ่งนั้นได้หรือไม่
Michael

13
stackoverflow.com/a/8156644/1206499ไม่ใช่การรอที่ยุ่งและnanosleepอาจเป็นตัวเลือกที่ดีกว่าเนื่องจากusleepล้าสมัย
jswetzen

4
ไม่ได้โปรดลองพูดถึงคำตอบของ @ HighCommander4 ซึ่งพกพาได้มากกว่าถ้าคุณมีคอมไพเลอร์ C ++ 11
einpoklum

6
usleep () เลิกใช้ใน POSIX ในปี 2001 และถูกนำออกในปี 2008
Jetski S-type

1270

ใน C ++ 11 คุณสามารถทำได้ด้วยสิ่งอำนวยความสะดวกห้องสมุดมาตรฐาน:

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

ชัดเจนและอ่านได้ไม่จำเป็นต้องเดาอีกต่อไปว่าsleep()ฟังก์ชั่นนั้นใช้หน่วยใด


6
std :: this_thread :: sleep_ สำหรับกำหนดจุดขัดจังหวะหรือไม่ ชอบเพิ่ม :: this_thread_sleep ทำอะไร
Martin Meeser

73
นี่เป็นวิธีที่ถูกต้องที่จะทำ ระยะเวลา ด้ายเป็นแพลตฟอร์มข้ามเช่นเดียวกับโครโน
โมฆะ

88
@Void วิธีที่ดีมากอย่างแน่นอน แต่ "ระยะเวลา" และ "ระยะเวลา" เป็นคำที่แข็งแกร่งมาก
นักฟิสิกส์บ้า

5
เป็นการนอนที่ยุ่งหรือเปล่า? ฉันต้องยอมจำนนต่อเธรดอื่นในระหว่างการนอนหลับ; ฉันสามารถใช้sleep_forสิ่งนั้นได้หรือไม่
Michael

14
@Michael: มันไม่ได้ยุ่งนอนหลับมันจะยอมแพ้กับหัวข้ออื่น ๆ
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/…
Martin Meeser

35

ใน Unix คุณสามารถใช้usleep

ใน Windows มีการนอนหลับ


4
และการโทรของ Windows เป็นมิลลิวินาที
shindigo

17
คุณต้องรวม <unistd.h> หรือ <Windows.h> ตามลำดับ
gbmhunter

ใช่ แต่ความละเอียดของเวลาจริงไม่สามารถเป็น 15-16 ms (แม้ว่าเครื่องที่ใช้ในการโทรคือ 1 ms) และเวลาต่ำสุดคือ 15-16 ms?
Peter Mortensen

33

ขึ้นอยู่กับแพลตฟอร์มของคุณว่าคุณมีusleepหรือnanosleepไม่มี usleepเลิกใช้แล้วและถูกลบออกจากมาตรฐาน POSIX ล่าสุด nanosleepเป็นที่ต้องการ


6
โปรดทราบว่าในขณะที่usleep()มีการประกาศใน<unistd.h>พลุกพล่านnanosleep()มีการประกาศใน/<time.h> <ctime>
gbmhunter

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 ยังคงอยู่ในสถานะ 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
ปัญหาอย่างหนึ่งของรหัสนั้นคือมันเป็นลูปที่ไม่ว่างก็จะยังคงใช้หน่วยประมวลผลหลักเดียว 100% ฟังก์ชั่นสลีปจะมีการใช้งานรอบการเรียกใช้ระบบปฏิบัติการที่จะทำให้เธรดปัจจุบันหลับและทำอย่างอื่นและจะปลุกเธรดเมื่อเวลาที่ระบุหมดอายุเท่านั้น
Ismael

คุณพูดถูก - มันจะกินซีพียู 100% เลยทีเดียว ดังนั้นนี่คือรหัสที่เขียนใหม่โดยใช้ฟังก์ชั่นการนอนหลับของระบบ - และยังคงเป็นระบบข้ามแพลตฟอร์ม:
Bart Grzybicki

@BartGrzybicki ฉันรู้ว่านี่เป็นคำตอบเก่าและทั้งหมด แต่ใน Visual Studio 2017 บนเครื่อง windows #ifdef WIN32ไม่ได้ประเมินว่าเป็นค่าเริ่มต้นจริง
kayleeFrye_onDeck

2
@kayleeFrye_onDeck รหัสผิด #ifdef _WIN32มันควรจะเป็น
Contango

1
@Contango ฉันรู้ว่า! แต่ไม่ใช่ตอนที่ฉันเขียน ... lol ขอบคุณสำหรับการติดตาม!
kayleeFrye_onDeck

17

nanosleepเป็นตัวเลือกที่ดีกว่าusleep- มีความยืดหยุ่นมากกว่าการขัดจังหวะ


6
ผมคุ้นเคยกับแต่ไม่usleep nanosleepคุณควรให้ตัวอย่างของการใช้งานบน Linux
jww

14
#include <windows.h>

ไวยากรณ์:

Sleep (  __in DWORD dwMilliseconds   );

การใช้งาน:

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

3
คุณต้องรวมอะไรกับสิ่งนี้
ʇolɐǝzǝɥʇ qoq

#include <WinBase.h>
foobar

7
ไม่คุณต้อง#include <windows.h>
ʇolɐǝzǝɥʇ qoq

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

อย่างไรก็ตามมีทางเลือกที่ดีกว่าในปัจจุบัน


ดูเหมือนจะไม่สามารถคอมไพล์ใน VS2017 บนเครื่อง Windows: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

สิ่งที่ส่วนหัวของคุณใช้สำหรับระยะเวลา ??
Totte Karlsson

<sys/time.h>@TotteKarlsson
Maxim Egorushkin

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

ฉันไม่ได้หมายความว่าอิซซี่นั้นขอโทษสำหรับความเข้าใจผิดของเรา ฉันหมายความว่าคุณสามารถป้อนจำนวนบวกของมิลลิวินาที ดังนั้นจะรอสักครู่หลายมิลลิวินาทีเพื่อปิดโปรแกรม หากคุณไม่เข้าใจโปรดพูดเช่นนั้นฉันจะอธิบายให้คุณมากขึ้น
พี่

ใช่ แต่การแก้ไขเวลาจริงคืออะไร ในบางกรณีอาจไม่ใช่ 15-16 ms ใช่หรือไม่ เช่นถ้าคุณใช้โหมดสลีป (3) มันจะนอนเป็นเวลา 3 มิลลิวินาทีหรือจะเป็น 15-16 มิลลิวินาที
Peter Mortensen

3

เลือกการโทรเป็นวิธีที่มีความแม่นยำมากขึ้น (สามารถระบุเวลาพักเครื่องเป็นนาโนวินาที)


แม้ว่านี่อาจเป็นคำแนะนำที่มีค่าในการแก้ปัญหา แต่คำตอบที่ดีก็แสดงให้เห็นถึงวิธีแก้ไข โปรดแก้ไขเพื่อให้รหัสตัวอย่างเพื่อแสดงความหมายของคุณ หรือลองเขียนสิ่งนี้เป็นความคิดเห็นแทน
Toby Speight

3

ใช้ Boost Asynchronous Input / Output Thread, Sleep สำหรับ x มิลลิวินาที;

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

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

จะเกิดอะไรขึ้นถ้าคุณพยายามนอนหลับเป็นเวลา 3 มิลลิวินาที? จะเป็น 15-16 มิลลิวินาทีแทนหรือไม่ คุณวัดมันได้หรือไม่
Peter Mortensen

1

คำถามนั้นเก่า แต่ฉันสามารถหาวิธีง่ายๆในการใช้แอพของฉัน คุณสามารถสร้างมาโคร C / C ++ ดังที่แสดงด้านล่างใช้:

#ifndef MACROS_H
#define MACROS_H

#include <unistd.h>

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

#endif // MACROS_H

1

จาก C ++ 14 โดยใช้ std และตามตัวอักษรตัวเลข:

#include <chrono>
#include <thread>

using namespace std::chrono;

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

0

เป็นการแทนที่ Win32 สำหรับระบบ POSIX:

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.