क्या सी से मिलीसेकंड में एक वैकल्पिक नींद समारोह है?


133

मेरे पास कुछ स्रोत कोड हैं जो विंडोज पर संकलित किए गए थे। मैं इसे Red Hat Linux पर चलाने के लिए परिवर्तित कर रहा हूँ।

स्रोत कोड में <windows.h>हेडर फ़ाइल शामिल है और प्रोग्रामर ने Sleep()मिलीसेकंड की अवधि के लिए प्रतीक्षा करने के लिए फ़ंक्शन का उपयोग किया है । यह लिनक्स पर काम नहीं करेगा।

हालाँकि, मैं sleep(seconds)फ़ंक्शन का उपयोग कर सकता हूं , लेकिन यह सेकंड में पूर्णांक का उपयोग करता है। मैं सेकंड में मिलीसेकंड परिवर्तित नहीं करना चाहता। वहाँ एक वैकल्पिक नींद समारोह है कि मैं लिनक्स पर gcc संकलन के साथ उपयोग कर सकते हैं?


sleep(/*seconds*/)में <unistd.h>काम करता है, लेकिन अगर मैं के साथ उपयोग printf("some things")के बिना \n, अपने नहीं काम करता है।
एस्माएलई

इस मामले में उपयोग के लिए, हमें fflush(stdout);प्रत्येक के बाद आउटपुट को फ्लश करना होगा printf()
EsmaeelE

जवाबों:


179

हां - पुराने POSIX मानकों को परिभाषित किया गया है usleep(), इसलिए यह लिनक्स पर उपलब्ध है:

   int usleep(useconds_t usec);

विवरण

Usleep () फ़ंक्शन कॉलिंग थ्रेड के निष्पादन को कम से कम usec micececonds के लिए निलंबित करता है। नींद को किसी भी प्रणाली की गतिविधि से या कॉल को संसाधित करने में या सिस्टम टाइमर की ग्रैन्युलैरिटी द्वारा थोड़ा बढ़ाया जा सकता है।

usleep()माइक्रोसेकंड लेता है , इसलिए आपको मिलीसेकंड में सोने के लिए इनपुट को 1000 से गुणा करना होगा।


usleep()तब से हटा दिया गया है और बाद में POSIX से हटा दिया गया है; नए कोड के nanosleep()लिए पसंद किया जाता है:

   #include <time.h>

   int nanosleep(const struct timespec *req, struct timespec *rem);

विवरण

nanosleep()कॉलिंग थ्रेड के निष्पादन को तब तक के लिए स्थगित कर देता है जब तक कि कम से कम निर्दिष्ट समय *reqबीत चुका हो, या सिग्नल की डिलीवरी जो कॉलिंग थ्रेड में एक हैंडलर के आह्वान को ट्रिगर करता है या जो प्रक्रिया को समाप्त करता है।

संरचना टाइमस्पेस का उपयोग नैनोसेकंड परिशुद्धता के साथ समय के अंतराल को निर्दिष्ट करने के लिए किया जाता है। इसे निम्नानुसार परिभाषित किया गया है:

       struct timespec {
           time_t tv_sec;        /* seconds */
           long   tv_nsec;       /* nanoseconds */
       };

एक उदाहरण msleep()फ़ंक्शन का उपयोग करके कार्यान्वित किया जाता है nanosleep(), यदि एक सिग्नल द्वारा बाधित होने पर नींद जारी रहती है:

#include <time.h>
#include <errno.h>    

/* msleep(): Sleep for the requested number of milliseconds. */
int msleep(long msec)
{
    struct timespec ts;
    int res;

    if (msec < 0)
    {
        errno = EINVAL;
        return -1;
    }

    ts.tv_sec = msec / 1000;
    ts.tv_nsec = (msec % 1000) * 1000000;

    do {
        res = nanosleep(&ts, &ts);
    } while (res && errno == EINTR);

    return res;
}

19
क्यों वे जटिल कार्यों के लिए सरल कार्यों को चित्रित करते रहते हैं। इसके बजाय अपने दिमाग को नैनोसेकंड () पर फोड़ने के साथ-साथ उस समय के लिए इस्तेमाल कर सकते हैं।

52

आप इस क्रॉस-प्लेटफ़ॉर्म फ़ंक्शन का उपयोग कर सकते हैं:

#ifdef WIN32
#include <windows.h>
#elif _POSIX_C_SOURCE >= 199309L
#include <time.h>   // for nanosleep
#else
#include <unistd.h> // for usleep
#endif

void sleep_ms(int milliseconds) // cross-platform sleep function
{
#ifdef WIN32
    Sleep(milliseconds);
#elif _POSIX_C_SOURCE >= 199309L
    struct timespec ts;
    ts.tv_sec = milliseconds / 1000;
    ts.tv_nsec = (milliseconds % 1000) * 1000000;
    nanosleep(&ts, NULL);
#else
    usleep(milliseconds * 1000);
#endif
}

3
जब हमारे पास नहीं है _POSIX_C_SOURCE >= 199309L, -ansiया के मामले में -std=c89, मैं struct timeval tv; tv.tv_sec = milliseconds / 1000; tv.tv_usec = milliseconds % 1000 * 1000; select(0, NULL, NULL, NULL, &tv);इसके बजाय का उपयोग करने की सलाह दूंगा usleep(milliseconds * 1000);। श्रेय यहाँ जाता है
जोश सैनफोर्ड

बहुत बढ़िया जवाब! ध्यान दें, यहाँ nanosleep()प्रलेखन है: man7.org/linux/man-pages/man2/nanosleep.2.html । यहां उपयोग किए गए प्रत्येक प्लेटफ़ॉर्म-विशिष्ट फ़ंक्शन के लिए दस्तावेज़ लिंक पोस्ट करना उपयोगी होगा।
गेब्रियल स्टेपल्स

यह भी ध्यान दें कि जब gcc -Wall -g3 -std=c11 -o sleep_test sleep_test.c && ./sleep_testलिनक्स उबंटू के साथ संकलित किया जाता है , तो जीसीसी संस्करण 4.8.4 के साथ, मुझे निम्न चेतावनी मिलती है warning: implicit declaration of function ‘usleep’ [-Wimplicit-function-declaration]:। समाधान निम्नलिखित 2 परिभाषित करने के लिए अपने कोड के बहुत ऊपर जोड़ रहा है: 1) #define __USE_POSIX199309और 2) #define _POSIX_C_SOURCE 199309Lदोनों को बिना किसी चेतावनी के संकलन करने के लिए कोड प्राप्त करना आवश्यक है (और nanoseconds()फ़ंक्शन का उपयोग करने के लिए , जो इसके पास उपलब्ध है)।
गेब्रियल स्टेपल्स

संबंधित उत्तर मैंने अभी बनाया: stackoverflow.com/a/55860234/4561887
गेब्रियल स्टेपल्स

32

वैकल्पिक रूप से usleep(), जिसे POSIX 2008 में परिभाषित नहीं किया गया है (हालाँकि इसे POSIX 2004 तक परिभाषित किया गया था, और यह स्पष्ट रूप से Linux और POSIX अनुपालन के इतिहास के साथ अन्य प्लेटफार्मों पर उपलब्ध है), POSIX 2008 मानक परिभाषित करता है nanosleep():

nanosleep - उच्च संकल्प नींद

#include <time.h>
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);

nanosleep()समारोह का कारण बन जाएगा वर्तमान धागा निष्पादन से निलंबित कर दिया है जब तक या तो समय अंतराल द्वारा निर्दिष्ट rqtpतर्क बीत जाने पर या एक संकेत बुला धागे के लिए दिया जाता है, और अपनी कार्रवाई एक संकेत को पकड़ने समारोह आह्वान करने के लिए या प्रक्रिया समाप्त करने के लिए है। निलंबन का समय अनुरोध से अधिक हो सकता है क्योंकि तर्क मान स्लीप रिज़ॉल्यूशन के पूर्णांक से कई गुना या सिस्टम द्वारा अन्य गतिविधि के समयबद्धन के कारण होता है। लेकिन, एक सिग्नल द्वारा बाधित होने के मामले को छोड़कर, निलंबन का समय निर्दिष्ट समय से कम नहीं होगा rqtp, जैसा कि सिस्टम घड़ी CLOCK_REALTIME द्वारा मापा जाता है।

nanosleep()फ़ंक्शन के उपयोग से किसी भी सिग्नल की कार्रवाई या रुकावट पर कोई प्रभाव नहीं पड़ता है।


24

Usleep से परे , NULL फ़ाइल डिस्क्रिप्टर सेट के साथ विनम्र चयन आपको माइक्रोसेकंड परिशुद्धता के साथ, और SIGALRMजटिलताओं के जोखिम के बिना विराम देगा ।

sigtimedwait और sigwaitinfo समान व्यवहार प्रदान करते हैं।


1
'सिग्लार्म के जोखिम के बिना': कौन सा जोखिम और कौन सा मामला? नींद और नींद बुला?
मैसिमो

2
@Massimo, के लिए जुड़ा हुआ कल्पना usleep अनिर्दिष्ट SIGALARM व्यवहार पर कई वाक्य है। (मूल रूप से, usleep और नींद वर्ष के माध्यम से लागू किया जा करने की अनुमति है अलार्म तंत्र है, जो आप कल्पना कर सकते हैं सुरक्षित उपयोग को मुश्किल होगा usleep और SIGALARM। मैं किसी भी आधुनिक प्रणाली यह इस तरह से है कि का पता नहीं है, लेकिन यह अभी भी में है कल्पना।)
पायलट


-7
#include <stdio.h>
#include <stdlib.h>
int main () {

puts("Program Will Sleep For 2 Seconds");

system("sleep 2");      // works for linux systems


return 0;
}

1
यह अभ्यस्त नींद मिलीसेकंड के लिए और भी अधिक उपरि का परिचय देता है, जो समय को और भी अधिक अविश्वसनीय बना देता है।
देवोलस

1
उदाहरण microseconds के लिए नहीं सोता है, इसके अलावा यह केवल समाधान (usleep) जैसे कुछ का उपयोग करने की तुलना में अच्छा नहीं है।
विक्टर Ocampo
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.