Domanda

Se dai un'occhiata al clock_gettime () La funzione, che è disponibile in tutti i BSD ed è attualmente definita come parte dello standard POSIX, si vede che esiste il supporto per almeno tre tipi di clock (molti sistemi supportano più di questi clock, ma in realtà lo standard POSIX richiede solo uno a essere presente, tutti gli altri sono opzionali):

  • CLOCK_REALTIME - POSIX richiede che questo sia presente. Questo è l'orologio da parete.

  • CLOCK_MONOTONIC - Non ho idea di cosa sia (e cosa significano i secondi SI), ma capisco che questo orologio non salterà mai indietro, può solo aumentare di valore monotonicamente.

  • CLOCK_UPTIME - Non riesco a vedere come questo sia diverso da CLOCK_MONOTONIC (il tempo di attività anche non salta mai indietro), ma almeno so che questo clock inizia a zero quando il kernel si avvia (mentre non è definito quale valore iniziale avrà CLOCK_MONOTONIC all'avvio del kernel)

Ignoriamo gli altri orologi per un secondo. CLOCK_REALTIME non è garantito per contare monotonicamente verso l'alto, giusto? Questo è il "tempo di sistema" attuale. Posso modificare l'ora del sistema a piacimento. Posso impostarlo 3 mesi negli ultimi o 5 anni nel futuro e ogni volta che il mio sistema sincronizza il tempo usando un server NTP in rete, il tempo potrebbe saltare avanti o indietro.

Ora abbiamo due funzioni di sospensione in un sistema BSD. sleep () e nanosleep () . Non sono sicuro, ma mi aspetto che sleep () sia implementato su nanosleep, dopotutto posso facilmente emulare sleep () usando nanosleep () e impostare solo il numero di secondi nella struttura temporale, mantenendo i nanosecondi zero .

Ho letto su molte fonti che queste funzioni funzionano effettivamente calcolando l'ora di sveglia (ottieni l'ora corrente, aggiungi la quantità di sonno ad essa) e il sistema verificherà ad intervalli regolari se l'ora corrente è più tardi rispetto al momento del risveglio e, in tal caso, riattiverà il thread. Il fatto che questo sia controllato solo a intervalli è il motivo per cui le pagine man dicono che il sonno corrente dormirà almeno per questo periodo di tempo (più breve solo se interrotto da un segnale), ma potrebbe dormire più a lungo (a seconda della frequenza il sistema verifica se siamo già passati al momento del risveglio e in base al tempo impiegato dallo scheduler per consentire a questo thread di essere eseguito di nuovo).

Questo è tutto perfettamente sano per me ... ma c'è una domanda che mi ha sempre infastidito:

Secondo varie fonti i sleep (almeno il nanosleep) usano CLOCK_REALTIME come orologio internamente. Ciò significa che se dico a nanosleep () di dormire per 30 secondi, quindi cambi il mio orologio di sistema a 1 ora in futuro, il thread si risveglierà quasi immediatamente (1 ora in futuro è molto più avanti del tempo di sveglia nanosleep ( ) calcolato). Anche questo va perfettamente bene. Tuttavia cosa succede se dico svegliarmi tra 30 secondi e quindi l'utente scopre che il suo orologio di sistema è un'ora avanti e imposta il suo orologio indietro di un'ora? Quindi il mio thread dormirà per 1 ora e 30 secondi? Dato che sarebbe piuttosto male.

È stato utile?

Soluzione

Per quanto ne so, le funzioni del sonno sono di solito implementate più come un contatore in decremento. Dici "dormi per 10 secondi", " che si traduce in "sospensione per 1000 tick di programma" nello scheduler e quindi ogni volta che lo scheduler verifica i processi di sospensione diminuisce il tempo rimanente.

In questo modo, il tempo di sonno sarà sempre una quantità di tempo reale per dormire, al contrario di dormire fino a qualche tempo in futuro. La ragione di ciò è come sospettavi, se scegliamo un momento in futuro, potremmo non arrivarci mai (o poterci arrivare in un periodo di tempo inaspettato). Ciò è coerente con ciò per cui vorresti usare il sonno in un programma. Non ha lo scopo di fare calcoli simili a quelli di un calendario.

Puoi anche fare un semplice test, mettere in pausa un programma per 30 secondi, usare il nix "tempo". comando per controllare per quanto tempo dura la funzione e dopo che inizia a cambiare l'orologio di sistema indietro di 5 minuti e vedere cosa succede.

Altri suggerimenti

Il thread controllerà un contatore interno impostato sulla durata del sonno e non sul punto finale del sonno. Il contatore interno utilizzato non ha nulla a che fare con l'ora corrente del sistema e pertanto non sarà interessato se si verificano cambiamenti nell'ora del sistema.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top