C++ <thread> Mój program wysypuje się

Odpowiedz Nowy wątek
2015-02-12 16:14
0

Witam, próbuje napisać program do automatycznego wyłączania komputera o konkretnej godzinie. Pętlę sprawdzającą porównującą aktualną godzinę do zaplanowanej wrzuciłem do osobnego wątku. I gdy program uruchamia osobny wątek to się wysypuje. (jeżeli uruchomię funkcje w tym samym wątku co main() wszystko działa. Nie mam błędów kompilacji.

//funkcja main();
//reszta kodu
switch (zm)
{
case '1':
{
    automatyzacja(1, 0, 0);
    break;
} 

bool tryb_automat = 1;

void automatyzacja(bool m, int aGodz, int aMin)
{
    //if (m == 1) tryb_automat = 1;
    //if (m == 0) tryb_automat = 0;

    if (tryb_automat == 1 && aGodz == 0 && aMin == 0)
    {
        cout << "\n\nPodaj o której godzinie chcesz wyłączyć komputer:\n";
    GODZINA:
        cout << "Godzina: ";
        cin >> Godz;
        if (Godz <= 0 || Godz > 23)
        {
            SetConsoleTextAttribute(hOut, FOREGROUND_RED | FOREGROUND_INTENSITY);
            cout << "\a\nWpisałeś niepoprawną godzinę! Spróbuj ponownie!\n";
            SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
            goto GODZINA;
        }

    MINUTY:
        cout << "\nMinut: ";
        cin >> Min;
        if (Min <= 0 || Min >= 60)
        {
            SetConsoleTextAttribute(hOut, FOREGROUND_RED | FOREGROUND_INTENSITY);
            cout << "\a\nWpisałeś niepoprawną ilość minut!!! Spróbuj ponownie!\n";
            SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
            goto MINUTY;
        }
        //cout << "\n\naGodz = " << aGodz << "\t\taMin = " << aMin;
        cout << "\nGotowe! Komputer wyłączy się o " << Godz << ":" << Min << endl;
    }
    thread wylacznik1(automat, aGodz, aMin); //tylko z tym nie działa
    //wylacznik1.join(); //działa
}

void automat(int aGodz, int aMin)
{
    while (tryb_automat == 1)
    {
        if (aGodz >= 0 && aGodz < 24 && aMin >= 0 && aMin <= 60)
        {
            update_czas();
            if (godzina == aGodz && minuta == aMin)
            {
                system("shutdown -s -f");
            }
        }
        Sleep(15000);
    }
}

Chcę aby funkcja automat() działała w tle gdyż w przyszłości cichłem dodać możliwość ustawienia kilku godzin przy których komputer będzie się wyłączać a oprócz tego chcę używać innych opcji programu więc nie mogę użyć wylacznik1.join();
Czy jest jakiś sposób aby ten osobny wątek działał bez używania funkcji join();?
Z góry dziękuję za odpowiedź.

edytowany 1x, ostatnio: km2442, 2015-02-12 16:15

Pozostało 580 znaków

2015-02-12 17:07
0

Niepotrzebne ci pętla i wątek, możesz użyć SetTimer.

Pozostało 580 znaków

2015-02-12 19:49
0

Funkcja niby fajna, ale nie umiem zmusić jej aby działała w tle, w dodatku nie wiem jak ją zaimplementować do mojego kodu powyżej. Czy mógłbyś mi z tym jakoś pomóc? Pozdrawiam.

Pozostało 580 znaków

2015-02-12 20:05
0

Dwie sprawy:

  1. Program z wątkiem ci się crashuje, bo najprawdopodobniej nie czekasz w wątku głównym na zakończenie pracy wątku pobocznego. Tutaj warto dodać, że na tę chwilę tworzysz wątek w pewnym scopie i po wyjściu z tego scopa wątek jest po prostu detachowany. Innymi słowy nie możesz już go joinować.

  2. Po co piszesz taki program jak mógłbyś napisać prosty batch?

    shutdown -s -t TUTAJ_RÓŻNICA_W_SEK_POMIĘDZY_CZASEM_ZAMKNIĘCIA_OS_A_AKTUALNYM_CZASEM 

    Ewentualnie zrób tak jak napisał @Azarien, tj użyj timera.

Pozostało 580 znaków

2015-02-12 20:15
0

Funkcja niby fajna, ale nie umiem zmusić jej aby działała w tle

najpierw zapytam: czego potrzebujesz na pierwszym planie, że potrzebne ci "tło"?

przypomniało mi się, ze SetTimer działa w oparciu o windowsową pętlę komunikatów, a w programie konsolowym jej zwykle nie ma - oczywiście można dodać, ale jeśli ma nie blokować "normalnego" konsolowego kodu, to musiałaby być mimo wszystko w osobnym wątku...

...chyba że cały program działałby w oparciu o pętlę komunikatów, ale musiałbyś pokazać więcej kodu.

edytowany 1x, ostatnio: Azarien, 2015-02-12 20:20

Pozostało 580 znaków

2015-02-12 20:33
0

@Satirev,

  1. to w takim razie jaki kod może działać wątku w tle?, właśnie Named Pipe chodzi mi przez cały okres działania programu z powodzeniem w tle...

    HANDLE hPipe;
    char buffer[1024];
    DWORD dwRead;
    
    hPipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\Pipe"),
        PIPE_ACCESS_DUPLEX | PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
        PIPE_WAIT,
        1,
        1024 * 16,
        1024 * 16,
        NMPWAIT_USE_DEFAULT_WAIT,
        NULL);
    while (hPipe != NULL)
    {
        if (ConnectNamedPipe(hPipe, NULL) != FALSE)
        {
            while (ReadFile(hPipe, buffer, sizeof(buffer), &dwRead, NULL) != FALSE)
            {
                if (widocznosc == 0) ukrywanie(1);
            }
        }
    
        DisconnectNamedPipe(hPipe);
    }
  2. Nie mogę od razu użyć shutdowna gdyż nie da się ustawić 2 lub więcej zadań na raz (np zamknięcie o 8:45 i o 15:10 czy zamknięcie o 10 i wylogowywanie o 12) Tu dopowiem że planuje zrobić aby program uruchamiał się przy starcie systemu i wykonywał zaplanowane czynności o konkretnej godzinie.

@Azarien tak jak pisałem wyżej potrzebuje w tle mieć zaplanowanie kilka operacji, w tle z powodzeniem chodzi też (jak wyżej) Named Pipe i dodatkowy void zczytujący polecenia z lini poleceń.... Dodatkowo zawsze chcę mieć możliwość dodawania / modyfikowania zaplanowanych zadań.

ja pytałem co się dzieje na pierwszym planie. jest pętla jakaś? - Azarien 2015-02-12 20:34

Pozostało 580 znaków

2015-02-12 20:46
0

W zasadzie, na pierwszym planie póki co jest pętla wyświetlająca menu programu i switch uruchamiający opcje wyłączania / restartowania / wylogowywania (+ te opcje wzbogacone o wybór dokładnego czasu)
Do tego funkcja wyświetlająca "O programie" i wyłączanie programu.
[Na ten czas nie umiem programować skomplikowanych programów... dopiero się uczę. Jestem samoukiem...]

edytowany 1x, ostatnio: km2442, 2015-02-12 20:48

Pozostało 580 znaków

2015-02-12 20:47
0
km2442 napisał(a):
  1. to w takim razie jaki kod może działać wątku w tle?

Każdy tylko musi być poprawnie napisany.

km2442 napisał(a):
  1. Nie mogę od razu użyć shutdowna gdyż nie da się ustawić 2 lub więcej zadań na raz (np zamknięcie o 8:45 i o 15:10 czy zamknięcie o 10 i wylogowywanie o 12) Tu dopowiem że planuje zrobić aby program uruchamiał się przy starcie systemu i wykonywał zaplanowane czynności o konkretnej godzinie.

Skoro możesz mieć kilka akcji (w tym reboot/shutdown) tzn. że twój program musi mieć jakiś local storage. Zatem równie dobrze mógłbyś to robić z poziomu skryptu batch/python/powershell/whatever.

W każdym razie skoro używasz named pipeów jako IPC to pewnie masz bardziej skomplikowaną architekturę. W takim wypadku użyj jakiegoś frameworka do timerów np. boost::asio (timer) albo napisz własny wrapper na std::thread/std::async emulujący timery.

edytowany 1x, ostatnio: satirev, 2015-02-12 21:12

Pozostało 580 znaków

2015-02-12 21:01
0
km2442 napisał(a):

Na ten czas nie umiem programować skomplikowanych programów... dopiero się uczę. Jestem samoukiem...

Tak jak napisałem wyżej, nie jestem jakimś mistrzem programowania tylko typowym n00bem... (C++ uczę się z ksiazki "Symfonia C++ Standard")
A co do tego Named Pipe, przepisałem go z przykładu z internetu aby dało się uruchomić tylko jedną instancję tego programu na raz (w miarę rozwijania programu dodam może jakieś inne funkcje named pipe jeśli mi się uda.)

Wracając do biblioteki <thread> Po maksymalnym uproszczeniu kodu doszedłem do wniosku:

 #include <iostream> 
#include <conio.h> 
#include <thread> 
#include <Windows.h>

using namespace std;

void t2() { *dowolny kod lub brak kodu* }

void t1() { thread test(t2); }

int main() { 
t1(); //wysypuje się  

thread test(t2); //działa 

_getch(); }

Pozostało 580 znaków

2015-02-12 21:12

Musisz jawnie wywołać detach() na tych wątkach (z tym, że na 100% nie powinieneś tak robić).

Pozostało 580 znaków

2015-02-12 22:27
0

@Satirev wiem, że nie powinienem detachować wątków ale takie rozwiązanie dla mnie działa. Dzięki za pomysł :D

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0