Milisaniye uyku


631

POSIX sleep(x)işlevinin programı x saniyeliğine uyku haline getirdiğini biliyorum . C ++ x milisaniye için programı uyku yapmak için bir işlevi var mı ?


7
Yine de, Windows'ta Sleep()milisaniye hassasiyete sahip olduğunu , ancak doğruluğunun daha büyük boyutlarda olabileceğini bilmelisiniz . 4 milisaniye uyuduğunu düşünebilirsin, ama aslında 400 uyuyabilirsin.
John Dibling

5
@John Dibling: Sanırım POSIX kullanıyor sleep, Sleep"x saniye" verildiğinde win32 değil .
CB Bailey

1
C ve C ++, hata ve uyumsuzluk kaynağı olabilen farklı ad yönetimine sahip olsa da, çoğu durumda C ++ 'da C üstbilgileri kullanmak iyidir. Ancak, hiçbir şeyin yanlış gitmediğinden kesinlikle emin olmak istiyorsanız, #includebir extern "C" {}bloğun içindeki C başlığı . Ayrıca, aynı projede C ve C ++ kaynak dosyalarınız varsa, özellikle her iki kaynak dosya türüne de aynı başlıkları eklerseniz (bu durumda bu gereklidir) herhangi bir sorunu önlemek için bunu yapmanız önemle tavsiye edilir. . Tamamen bir C ++ projeniz varsa, hiç sorun olmadan çalışabilir.
adam10603

2
@JohnDibling no, 400ms değil. Şimdiye kadar almış olabileceğiniz en kötü hassasiyet, GetTickCount55ms çözünürlüğe sahip Windows 9x'ten; sonraki sürümlerde 16 ms veya daha az çözünürlük vardı. Bir kullanıcı , Sleep'ten 16ms çözünürlük aldığını düşündü, ancak daha sonra Sleepkendisinin oldukça doğru olduğunu bildirdi ve zamanın GetTickCountölçülmesini ölçmek için kullanıldığında görünen belirsizliğe neden oldu .
Qwertie

Yanıtlar:


457

Milisaniye için standart bir C API'sinin olmadığını unutmayın, bu nedenle (Unix'te) razı olmanız gerekir usleep, bu da mikrosaniye kabul eder:

#include <unistd.h>

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

2
Yoğun bir uyku mı? Uyku sırasında başka bir iş parçacığı vermek gerekir; bunun için kullanabilir miyim usleep?
Michael

13
Yoğun bir bekleme stackoverflow.com/a/8156644/1206499 değildir ve nanosleepkullanılmadığından daha iyi bir seçim olabilir usleep.
jswetzen

4
Niet, lütfen bir C ++ 11 derleyiciniz varsa daha taşınabilir olan @ HighCommander4'ün cevabından bahsetmeyi düşünün.
einpoklum

6
usleep () 2001 yılında POSIX'te kullanımdan kaldırıldı ve 2008'de kaldırıldı.
Jetski S-tipi

1270

C ++ 11'de bunu standart kütüphane olanaklarıyla yapabilirsiniz:

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

Net ve okunabilir, artık sleep()fonksiyonun hangi birimleri aldığını tahmin etmeye gerek yok .


6
Std :: this_thread :: sleep_for bir kesinti noktası tanımlar mı? Boost :: like_thread_sleep gibi mi?
Martin Meeser

73
Bunu yapmanın doğru yolu budur. Dönemi. İplik çapraz platform ve kronondur.
Void

88
@Geçersiz. Kesinlikle çok iyi bir yol, ama "ve" dönem "çok güçlü kelimeler.
Deli Fizikçi

5
Yoğun bir uyku mı? Uyku sırasında başka bir iş parçacığı vermek gerekir; bunun için kullanabilir miyim sleep_for?
Michael

14
@Michael: Yoğun bir uyku değil, diğer iplikleri de verecek.
HighCommander4

83

Taşınabilir kalmak için Boost :: Sleeping for Thread uygulamasını kullanabilirsiniz :

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

Bu cevap yineleniyor ve bu soruya daha önce gönderilmişti. Belki orada da bazı kullanışlı cevaplar bulabilirsiniz.


6
Çok iş parçacıklı bir ortamda boost::this_thread::sleep, kodunuza bir kesinti noktası eklediğini unutmayın. boost.org/doc/libs/1_49_0/doc/html/thread/…
Martin Meeser

35

Unix'te bizi uykuda kullanabilirsiniz .

Windows'da Uyku var .


4
ve Windows çağrısı milisaniye cinsindendir.
shindigo

17
Sırasıyla <unistd.h> veya <Windows.h> eklemeniz gerekir.
gbmhunter

Evet, ancak gerçek zaman çözünürlüğü 15-16 ms (çağrıdaki ünite 1 ms olsa bile) ve bu nedenle minimum süre 15-16 ms olamaz mı?
Peter Mortensen

33

Platformunuza bağlı olarak sahip olabilirsiniz usleepveya nanosleepmevcut olabilirsiniz . usleepkullanımdan kaldırıldı ve en son POSIX standardından silindi; nanosleeptercih edilir.


6
Süre o Not usleep()beyan edilir <unistd.h>, karışıklığa, nanosleep()beyan edilir <time.h>/ ' <ctime>.
gbmhunter

27

Neden time.h kütüphanesini kullanmıyorsunuz? Windows ve POSIX sistemlerinde çalışır:

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

Düzeltilmiş kod - CPU artık IDLE durumunda kalıyor [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
Bu kodla ilgili sorunlardan biri, meşgul bir döngü olması, tek bir işlemci çekirdeğinin% 100'ünü kullanmaya devam etmesidir. Uyku işlevi, geçerli iş parçacığını uyku moduna sokacak ve başka bir şey yapacak bir OS çağrısı etrafında uygulanır ve yalnızca belirtilen süre sona erdiğinde iş parçacığını uyandırır.
Ismael

Haklısın - bir CPU çekirdeğinin% 100'ünü tüketecek. İşte burada sistem uyku fonksiyonlarını kullanarak yeniden yazılan kod - ve hala çapraz platform:
Bart Grzybicki

@BartGrzybicki bu eski bir cevap olduğunu biliyorum ve tüm, ama bir Windows makinede Visual Studio 2017'de, #ifdef WIN32varsayılan olarak gerçek olarak değerlendirmez.
kayleeFrye_onDeck

2
@kayleeFrye_onDeck Kodu yanlış. Olmalı #ifdef _WIN32.
Contango

1
@Contango Bunu biliyordum! Ama bunu yazarken ... lol. Takip için teşekkürler!
kayleeFrye_onDeck

17

nanosleepdaha iyi bir seçimdir usleep- kesintilere karşı daha dayanıklıdır.


6
Bildim usleep, ama bilmiyordum nanosleep. Linux'ta kullanmanın bir örneğini vermelisiniz.
jww


7

MS Visual C ++ 10.0 kullanıyorsanız, bunu standart kitaplık olanaklarıyla yapabilirsiniz:

Concurrency::wait(milliseconds);

ihtiyacın olacak:

#include <concrt.h>

10
Gerçekten demek istemediğiniz zaman "standart" kelimesini kullanmayın. <concrt.h>olduğu değil bir Standart Kütüphanesi Öncü - bu platform kütüphane olabilir; bu durumda önkoşulları açıkça belirtmelisiniz.
Toby Speight

5

selectİşlevi (POSIX, Linux ve Windows) olan platformlarda şunları yapabilirsiniz:

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

Ancak, günümüzde daha iyi alternatifler mevcuttur.


Bir Windows makinesinde VS2017'de derlenemiyor gibi görünüyor:error LNK2019: unresolved external symbol _select@20 referenced in function "void __cdecl sleep(unsigned long)" (?sleep@@YAXK@Z)
kayleeFrye_onDeck

@kayleeFrye_onDeck Derleme yapar. Sadece bağlantı vermiyor. Windows belgelerini arayın.
Maxim Egorushkin

timeval için hangi başlığı kullanıyorsunuz ??
Totte Karlsson

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

4

C ++ programınızı uyku yolu Sleep(int)yöntemdir. Bunun için başlık dosyası#include "windows.h."

Örneğin:

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

Uyuduğu süre milisaniye cinsinden ölçülür ve sınırı yoktur.

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

3
Ne demek sınırı yok? Kesinlikle 0xFFFFFFFE olan sınırı vardır. 0xFFFFFFFF için beklemek zaman aşımına uğramayacaktır (yani program bitene kadar bekleyecektir).
Izzy

Öyle demek istemedim Izzy, yanlış anlaşıldığımız için üzgünüm. Yani herhangi bir pozitif milisaniye girebilirsiniz. Bu yüzden programı kapatmak için milisaniyeyi bekleyecek. Eğer anlamadıysanız lütfen söyleyin, size daha fazla açıklayacağım.
Phi

Evet, ama gerçek zaman çözünürlüğü nedir? Bazı durumlarda 15-16 ms olamaz mı? Örneğin, Uyku (3) kullanırsanız, aslında 3 ms uyuyacak mı yoksa 15-16 ms mi olacak?
Peter Mortensen

3

Seçme çağrısı daha fazla hassasiyete sahip olmanın bir yoludur (uyku süresi nanosaniye olarak belirtilebilir).


Bu, sorunu çözmek için değerli bir ipucu olsa da, iyi bir cevap da çözümü gösterir. Ne demek istediğinizi göstermek için örnek kod sağlamak üzere lütfen düzenleyin . Alternatif olarak, bunun yerine yorum olarak yazmayı düşünün.
Toby Speight

3

Boost asenkron giriş / çıkış dişlerini kullanın, x milisaniye boyunca uyku;

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

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

3 milisaniye uyumaya çalışırsanız gerçekte ne olur? Bunun yerine 15-16 milisaniye mi olacak? Ölçtün mü?
Peter Mortensen

1

Soru eski, ama bunu uygulamam için basit bir yol bulmayı başardım. Aşağıda gösterildiği gibi bir C / C ++ makrosu oluşturabilirsiniz:

#ifndef MACROS_H
#define MACROS_H

#include <unistd.h>

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

#endif // MACROS_H

1

Std ve sayısal değişmezlerini kullanarak C ++ 14'ten:

#include <chrono>
#include <thread>

using namespace std::chrono;

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

0

POSIX sistemleri için bir Win32 yedeği olarak:

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

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

Tercih nanosleep()et usleep(): İkincisi kullanımdan kaldırıldı ve en son POSIX standardından silindi.
Toby Speight
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.