Tidur selama milidetik


632

Saya tahu sleep(x)fungsi POSIX membuat program tidur selama x detik. Apakah ada fungsi untuk membuat program tidur selama x milidetik di C ++?


7
Anda harus menyadari bahwa, di Windows, Sleep()memiliki ketepatan milidetik , tetapi akurasinya bisa lebih tinggi. Anda mungkin berpikir tidur Anda selama 4 milidetik, tetapi sebenarnya tidur selama 400.
John Dibling

5
@ John Dibling: Saya pikir dia menggunakan POSIX sleep, bukan win32 Sleepdiberi "x detik".
CB Bailey

1
Meskipun C dan C ++ memiliki nama mangling yang berbeda, yang dapat menjadi sumber bug dan ketidakcocokan, dalam kebanyakan kasus tidak masalah menggunakan header C di C ++. Namun, jika Anda ingin benar-benar yakin bahwa tidak ada yang salah, #includeheader C di dalam extern "C" {}blok. Juga, jika Anda memiliki file sumber C dan C ++ dalam proyek yang sama, sangat disarankan agar Anda melakukan ini untuk menghindari masalah, terutama jika Anda menyertakan header yang sama di kedua jenis file sumber (dalam hal ini diperlukan) . Jika Anda memiliki proyek C ++ murni, mungkin hanya bekerja tanpa masalah sama sekali.
adam10603

2
@ JohnDibling no, bukan 400ms. Ketepatan terburuk yang mungkin Anda dapatkan adalah dari Windows 9x, yang GetTickCountmemiliki resolusi 55ms; versi selanjutnya memiliki resolusi 16ms atau kurang. Seorang pengguna mengira ia mendapatkan resolusi 16ms dari Sleep tetapi kemudian melaporkan bahwa Sleepitu sendiri cukup akurat, dan ketidaktepatan yang disebabkan oleh penggunaan GetTickCountuntuk mengukur berlalunya waktu.
Qwertie

Jawaban:


457

Perhatikan bahwa tidak ada API C standar untuk milidetik, jadi (pada Unix) Anda harus puas usleep, yang menerima mikrodetik:

#include <unistd.h>

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

2
Apakah ini tidur yang sibuk? Saya perlu menyerah pada utas lain selama tidur; dapat saya gunakan usleepuntuk itu
Michael

13
Ini bukan menunggu stackoverflow.com/a/8156644/1206499 yang sibuk , dan nanosleepmungkin merupakan pilihan yang lebih baik karena usleepsudah usang.
jswetzen

4
Niet, harap pertimbangkan menyebutkan jawaban @ HighCommander4 yang lebih portabel jika Anda memiliki kompiler C ++ 11.
einpoklum

6
usleep () dihentikan dalam POSIX pada tahun 2001 dan dihapus pada tahun 2008.
Jetski S-type

1271

Di C ++ 11, Anda dapat melakukan ini dengan fasilitas perpustakaan standar:

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

Jelas dan mudah dibaca, tidak perlu lagi menebak unit apa yang sleep()dibutuhkan fungsi.


6
Apakah std :: this_thread :: sleep_for mendefinisikan titik interupsi? Seperti boost :: this_thread_sleep tidak?
Martin Meeser

73
Ini cara yang tepat untuk melakukannya. Titik. Utas adalah lintas platform dan juga chrono.
Batal

88
@Kosong. Cara yang sangat bagus tentu saja, tetapi "the" and "period" adalah kata-kata yang sangat kuat.
Fisikawan Gila

5
Apakah ini tidur yang sibuk? Saya perlu menyerah pada utas lain selama tidur; dapat saya gunakan sleep_foruntuk itu
Michael

14
@Michael: Ini bukan tidur yang sibuk, itu akan menghasilkan utas lainnya.
HighCommander4

83

Untuk tetap portabel Anda bisa menggunakan Boost :: Thread untuk tidur:

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

Jawaban ini adalah duplikat dan telah diposting dalam pertanyaan ini sebelumnya. Mungkin Anda bisa menemukan beberapa jawaban yang dapat digunakan di sana juga.


6
Ingatlah bahwa - di lingkungan multi-utas - boost::this_thread::sleepmenambahkan titik interupsi ke kode Anda. boost.org/doc/libs/1_49_0/doc/html/thread/…
Martin Meeser

35

Di Unix Anda bisa menggunakan usleep .

Di Windows ada Sleep .


4
dan panggilan Windows dalam milidetik.
shindigo

17
Anda harus memasukkan masing-masing <unistd.h> atau <Windows.h>.
gbmhunter

Ya, tetapi tidak bisakah resolusi waktu aktual menjadi 15-16 ms (bahkan jika unit dalam panggilan adalah 1 ms) dan dengan demikian waktu minimum adalah 15-16 ms?
Peter Mortensen

33

Tergantung pada platform Anda, Anda mungkin memiliki usleepatau nanosleeptersedia. usleepsudah usang dan telah dihapus dari standar POSIX terbaru; nanosleeplebih disukai.


6
Perhatikan bahwa sementara usleep()dideklarasikan dalam <unistd.h>, secara membingungkan, nanosleep()dinyatakan dalam <time.h>/ <ctime>.
gbmhunter

27

Mengapa tidak menggunakan perpustakaan time.h? Berjalan pada sistem Windows dan 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;
}

Kode yang diperbaiki - sekarang CPU tetap dalam status 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
Salah satu masalah dengan kode itu adalah bahwa itu adalah loop sibuk, akan terus menggunakan 100% dari inti prosesor tunggal. Fungsi sleep diimplementasikan di sekitar panggilan OS yang akan mengaktifkan thread saat ini dan melakukan sesuatu yang lain, dan hanya akan membangunkan thread ketika waktu yang ditentukan berakhir.
Ismael

Anda benar - itu akan mengkonsumsi 100% dari satu inti CPU. Jadi di sini adalah kode yang ditulis ulang menggunakan fungsi sistem tidur - dan itu masih lintas platform:
Bart Grzybicki

@ BartGrzybicki saya tahu ini adalah jawaban lama dan semuanya, tetapi dalam Visual Studio 2017 di mesin windows, #ifdef WIN32tidak mengevaluasi sebagai benar secara default.
kayleeFrye_onDeck

2
@kayleeFrye_onDeck Code salah. Seharusnya begitu #ifdef _WIN32.
Contango

1
@Contango Saya tahu itu! Tetapi tidak ketika saya menulis itu ... lol. Terima kasih atas tindak lanjutnya!
kayleeFrye_onDeck

17

nanosleepadalah pilihan yang lebih baik daripada usleep- lebih tahan terhadap interupsi.


6
Saya kenal usleep, tetapi tidak nanosleep. Anda harus memberikan contoh menggunakannya di Linux.
jww


7

Jika menggunakan MS Visual C ++ 10.0, Anda dapat melakukan ini dengan fasilitas perpustakaan standar:

Concurrency::wait(milliseconds);

Anda akan perlu:

#include <concrt.h>

10
Jangan menggunakan kata "standar" ketika Anda tidak benar-benar bersungguh-sungguh. <concrt.h>adalah tidak header Standard Library - mungkin perpustakaan platform yang; dalam hal ini Anda harus menyatakan prasyarat dengan jelas.
Toby Speight

5

Pada platform dengan selectfungsi (POSIX, Linux, dan Windows) yang dapat Anda lakukan:

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

Namun, ada alternatif yang lebih baik tersedia saat ini.


Tampaknya tidak dapat mengkompilasi dalam VS2017 pada mesin Windows:error LNK2019: unresolved external symbol _select@20 referenced in function "void __cdecl sleep(unsigned long)" (?sleep@@YAXK@Z)
kayleeFrye_onDeck

@kayleeFrye_onDeck Itu mengkompilasi. Hanya saja tidak terhubung. Cari Windows docs Anda.
Maxim Egorushkin

header apa yang Anda gunakan untuk jangka waktu ??
Totte Karlsson

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

4

Cara untuk tidur program Anda di C ++ adalah Sleep(int)metode. File header untuk itu adalah#include "windows.h."

Sebagai contoh:

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

Waktu tidur diukur dalam milidetik dan tidak memiliki batas.

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

3
Apa maksudmu tidak ada batasan? Itu pasti memiliki batas yaitu 0xFFFFFFFE. Menunggu 0xFFFFFFFF tidak akan habis (artinya akan menunggu sampai program berakhir).
Izzy

Aku tidak bermaksud seperti itu, Izzy, maaf atas kesalahpahaman kita. Maksud saya, Anda dapat memasukkan jumlah milidetik positif. Jadi itu akan menunggu banyak milidetik untuk menutup program. Jika Anda tidak mengerti, tolong katakan demikian, saya akan menjelaskan lebih banyak kepada Anda.
Phi

Ya, tapi apa itu resolusi waktu yang sebenarnya? Mungkinkah itu 15-16 ms dalam beberapa kasus? Misalnya, jika Anda menggunakan Sleep (3) apakah akan benar-benar tidur selama 3 ms atau malah 15-16 ms?
Peter Mortensen

3

Pilih panggilan adalah cara untuk memiliki lebih presisi (waktu tidur dapat ditentukan dalam nanodetik).


Meskipun ini mungkin merupakan petunjuk yang berharga untuk menyelesaikan masalah, jawaban yang baik juga menunjukkan solusinya. Harap edit untuk memberikan kode contoh untuk menunjukkan maksud Anda. Sebagai alternatif, pertimbangkan menulis ini sebagai komentar.
Toby Speight

3

Gunakan Boost input / output thread asynchronous, sleep selama x milidetik;

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

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

Apa yang sebenarnya akan terjadi jika Anda mencoba tidur selama 3 milidetik? Apakah itu akan menjadi 15-16 milidetik saja? Sudahkah Anda mengukurnya?
Peter Mortensen

1

Pertanyaannya sudah lama, tetapi saya berhasil menemukan cara sederhana untuk memiliki ini di aplikasi saya. Anda dapat membuat makro C / C ++ seperti yang ditunjukkan di bawah ini menggunakannya:

#ifndef MACROS_H
#define MACROS_H

#include <unistd.h>

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

#endif // MACROS_H

1

Dari C ++ 14 menggunakan std dan juga literal numeriknya:

#include <chrono>
#include <thread>

using namespace std::chrono;

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

0

Sebagai pengganti Win32 untuk sistem POSIX:

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

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

Lebih memilih nanosleep()untuk usleep(): yang terakhir sudah ditinggalkan dan telah dihapus dari yang paling standar POSIX baru-baru ini.
Toby Speight
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.