Du må være registrert og logget inn for å kunne legge ut innlegg på freak.no
X
LOGG INN
... eller du kan registrere deg nå
Dette nettstedet er avhengig av annonseinntekter for å holde driften og videre utvikling igang. Vi liker ikke reklame heller, men alternativene er ikke mange. Vær snill å vurder å slå av annonseblokkering, eller å abonnere på en reklamefri utgave av nettstedet.
  8 2257
Jeg har startet på å utvikle en applikasjon som skal brukes til loggføring, men under planleggingsfasen har jeg støtt på et problem med timing. Applikasjonen består hovedsakelig av en MySQL/MariaDB motor, 2 socket tilkobinger til 2 maskiner på samme lokale nettverket og en kode som skal kjøres hvert sekund.

Problemet er at koden som skal kjøres hvert sekund kan variere i kjøretid. Jeg har skrevet en lignende testkode, å kjørt den i loop for å måle tiden hver loop bruker, kjøretiden varierer mellom 200-700ms. Hvis jeg bruker sleep ( 800 ) så vil kjøretiden være mellom 1 sekund og 1,5 sekund og det er altfor upresist. Jeg trenger å kjøre denne koden med en nøyaktighet på 1000 ms.

Jeg har pønsket ut noen alternativer.

1. Lagre starttid og måle tiden koden bruker på å kjøre for så å subtraktere den fra det sekundet den skal bruke. Men jeg er bekymret for at koden kan bruke over 1 sekund på å kjøre hvis det er mye load på maskinen koden skal kjøre på, eller på nettverket.

2. Bruke cron job i operativ systemet (Debian) for å starte koden med et interval på 1 sekund. Men dette vil føre til unødvendig mye ressursbruk med tanke på at koden da må opprette både MySQL/MariaDB og socket tilkoblingene på nytt hver gang den starter.

3. Starte en ny thread hvert sekund, der koden kjørers også terminere thread'en når koden er ferdig, dette tror jeg er det beste alternativet da man kan bruke eksisterende tilkoblinger og man trenger ikkje å bekymre seg over at koden bruker mer enn 1 sekund å kjøre.

Kom gjerne med deres tanker eller ideer rundt dette. Og finnes det noen library i C++ som gjør det mulig å starte en funksjon/metode med et gitt interval? Jo mer nøyaktig timingen er jo bedre er det.
Alternativ 3 er mest ryddig. Det du da må ta høyde for i koden din er at samme jobb kan kjøre opp til flere ganger.
Overskuddsmateriell
Du bør vurdere om du vil kjøre jobben flere ganger på samme tid hvis den bruker mer enn 1 sek på å kjøre. Er det at den jobber for fullt mens den skaffer dataene så vil bare probleme eksalere jo flere tråder.

Selv har jeg valgt å gå etter uptime når jeg programerer min Arduino, men her risikerer jeg da at sekunder mangler om den bruker over 1 sek, men timingen vil fortsatt være korrekt.

Kode

delay(1000 - (millis() % 1000));
War room
0xFF's Avatar
Trådstarter Donor
Ja, jeg har tatt høyde for at samme operasjon kan kjøres flere ganger med tanke på at vi snakker om multithreading. Men det er ingen kritisk data som kan overskrives. Jeg ser for meg å allokere et nytt objekt av en klasse for hver ny thread, der verdiene lagres for kun intern bruk innenfor klassen, men klassene deler MySQL/MariaDB tilkobling og socket tilkoblingene. MySQL/MariaDB library er threadsafe, mens jeg kommer til å bruke mutex til å låse socket tilkoblingen når den er i bruk.
Sitat av 0xFF Vis innlegg
Ja, jeg har tatt høyde for at samme operasjon kan kjøres flere ganger med tanke på at vi snakker om multithreading. Men det er ingen kritisk data som kan overskrives. Jeg ser for meg å allokere et nytt objekt av en klasse for hver ny thread, der verdiene lagres for kun intern bruk innenfor klassen, men klassene deler MySQL/MariaDB tilkobling og socket tilkoblingene. MySQL/MariaDB library er threadsafe, mens jeg kommer til å bruke mutex til å låse socket tilkoblingen når den er i bruk.
Vis hele sitatet...
Tidsbruk på minnehåndtering kan variere fryktelig mye. Dersom store deler av kjøretiden bår med på allokere og deallokere minne, så vil det bli frykelig vanskelig å få konsistente kjøretider. Men jeg skjønner ikke helt - starter du hele koden på nytt hvert sekund? Er det i såfall nødvendig, eller kunne du hatt den liggende som en konstant kjørende prosess i bakgrunnen?
Skal du ha scheduling-funksjonalitet må du nok lete utenfor standard headers, men du kan jo sikkert gjøre noe slik:

Kode

#include <iostream>
#include <time.h>
#include <thread>

void do_stuff(int i){
    std::cout << i << std::endl;
}

int main(){
    clock_t t;
    
    for(int i = 0; i < 10; i++){
        t = clock();
        std::thread (do_stuff, i).detach();
        while(clock() - t < CLOCKS_PER_SEC);
    }

}
Forøvrig kan ikke cron kjøres hvert sekund. Hvert minutt er laveste intervall.
Jeg ville gjort det så enkelt som å hente ut klokkeslettet i en while-løkke med sleep(10) per runde. Hver gang klokka ruller over til et nytt sekund så kjøres koden.
Da får du absolutt ikke tatt høyde for de gangene koden bruker mer enn ett sekund.