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 ++?

Prasanth Madhavan
sumber
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);
Niet the Dark Absol
sumber
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.

Komandan Tinggi4
sumber
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.

MOnsDaR
sumber
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 .

INS
sumber
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.

CB Bailey
sumber
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;
}
Bart Grzybicki
sumber
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.

Johan Kotlinski
sumber
6
Saya kenal usleep, tetapi tidak nanosleep. Anda harus memberikan contoh menggunakannya di Linux.
jww
14
#include <windows.h>

Sintaksis:

Sleep (  __in DWORD dwMilliseconds   );

Pemakaian:

Sleep (1000); //Sleeps for 1000 ms or 1 sec
foobar
sumber
3
Apa yang perlu Anda sertakan untuk ini?
ʇolɐǝz ǝɥʇ qoq
#include <WinBase.h>
foobar
7
Tidak, Anda perlu#include <windows.h>
ʇolɐǝz ǝɥʇ qoq
7
Pertanyaannya sangat menyiratkan bahwa solusi POSIX diperlukan.
Toby Speight
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>
Metronit
sumber
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.

Maxim Egorushkin
sumber
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
Phi
sumber
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).

Madhava Gaikwad
sumber
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));
Anum Sheraz
sumber
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
VPZ
sumber
1

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

#include <chrono>
#include <thread>

using namespace std::chrono;

std::this_thread::sleep_for(123ms);
Martin Flaska
sumber
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
}
lama12345
sumber
Lebih memilih nanosleep()untuk usleep(): yang terakhir sudah ditinggalkan dan telah dihapus dari yang paling standar POSIX baru-baru ini.
Toby Speight