Nie jesteś zalogowany.
Jeśli nie posiadasz konta, zarejestruj je już teraz! Pozwoli Ci ono w pełni korzystać z naszego serwisu. Spamerom dziękujemy!

Ogłoszenie

Prosimy o pomoc dla małej Julki — przekaż 1% podatku na Fundacji Dzieciom zdazyć z Pomocą.
Więcej informacji na dug.net.pl/pomagamy/.

#1  2010-01-19 18:08:56

  Blackhole - Użytkownik

Blackhole
Użytkownik
Skąd: G. Śląsk
Zarejestrowany: 2005-09-07
Serwis

[solved] Własny program uruchomiony w tle (oraz jego restart)

Hej. Może będzie ktoś w stanie pomóc, choć sprawa dotyczy dewelopmentu.
Mam własny program, który co sek. (w środku jest pauza w pętli) sprawdza zawartość jakiegoś pliku i na jej podstawie zapisuje coś w innym pliku. Jeśli uruchomiony jest na pierwszym planie, to plik jest sprawdzany i wynik zapisywany. Jeśli jednak uruchomię go w tle, to jest tak, jakby nie działał. Jaka może być tego przyczyna?
Chciałbym też, by ten program sprawdzał, czy nie zmieniła się jego wersja binarna (nie został przekompilowany). Jeśli się zmieniła, to powinien uruchomić nowy proces siebie i zabić proces działający do tej chwili. Nie mam pomysłu na to. Wydaje mi się, że jeśli uruchomię coś poprzez komendę "system()", to będzie to dziecko procesu, który je wywołał i jak ten proces wywołujący się zakończy, to jego dzieci też.
Z góry dzięki za jakąkolwiek pomoc.

Ostatnio edytowany przez Blackhole (2010-01-22 09:00:37)


Ściskam prawicę, Jacek

http://doscniewoli.plPoznaj prawdę o pieniądzach
Free energy exists!

Offline

 

#2  2010-01-19 20:00:22

  bercik - Moderator Mamut

bercik
Moderator Mamut
Skąd: Warszawa
Zarejestrowany: 2006-09-23
Serwis

Re: [solved] Własny program uruchomiony w tle (oraz jego restart)

u mnie dziala:

Kod:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main() {
    FILE *plik;
    char buf [20];
    int tmp;

    plik=fopen("/tmp/plik1.txt", "w");
    fputs( "Hello World !!!\n", plik );
    fclose(plik);
    
    plik=fopen("/tmp/plik2.txt", "w");
    fputs( "0", plik );
    fclose(plik);

    while(1) {
        sleep(1);

        plik=fopen("/tmp/plik2.txt", "r");
        fgets(buf, 20, plik);
        fclose(plik);

        tmp=atoi(buf);
        if (tmp == 1) {
            plik=fopen("/tmp/plik1.txt", "w");
            fputs( "Ala ma kota\n", plik );
            fclose(plik);
        } else if (tmp == 2) {
            plik=fopen("/tmp/plik1.txt", "w");
            fputs( "Kot ma Ale\n", plik );
            fclose(plik);
        } else if (tmp == 3) {
            execl("/tmp/a.out", "/tmp/a.out", 0);
            perror ("execl");
        }
    }
}

wpisanie 1 lub 2 daje rozne zapisy, a wpisanie 3 daje zrestartowanie programu - ponowne wczytanie wykonywanego pliku binarnego (zapis Hello World)

sekwencje testowa mozna wywolac komenda

Kod:

./a.out & sleep 1; cat plik1.txt; echo 1 > plik2.txt; sleep 1; cat plik1.txt; echo 2 > plik2.txt; sleep 1; cat plik1.txt; echo 3 > plik2.txt; sleep 1; cat plik1.txt

Ostatnio edytowany przez bercik (2010-01-19 20:02:37)


"Wszyscy wiedzą, że czegoś zrobić nie można. Ale przypadkowo znajduje się jakiś nieuk, który tego nie wie. I on właśnie robi odkrycie." (A.Einstein)

Offline

 

#3  2010-01-20 14:28:44

  Blackhole - Użytkownik

Blackhole
Użytkownik
Skąd: G. Śląsk
Zarejestrowany: 2005-09-07
Serwis

Re: [solved] Własny program uruchomiony w tle (oraz jego restart)

Dzięki, bercik. Spróbuję to wykorzystać.


Ściskam prawicę, Jacek

http://doscniewoli.plPoznaj prawdę o pieniądzach
Free energy exists!

Offline

 

#4  2010-01-20 18:26:29

  Blackhole - Użytkownik

Blackhole
Użytkownik
Skąd: G. Śląsk
Zarejestrowany: 2005-09-07
Serwis

Re: [solved] Własny program uruchomiony w tle (oraz jego restart)

Załatwiłem tak przeładowywanie się po kompilacji:

Kod:

                // (...)
//                cout << "Working in background..." << endl;
                struct stat attrib;
                stat(argv[0], &attrib);
                int last_compile;
                last_compile = attrib.st_mtime;
                do {
                        // (...)
                        usleep(200000);

                        stat(argv[0], &attrib);
                        if (last_compile != attrib.st_mtime) {
                                execl(argv[0], argv[0], argv[1], argv[2], argv[3], 0);
                        }
                } while(true);
                (...)

I działa dobrze - tak sądzę.
Nie wiem jednak, dlaczego uruchomienie programu w tle powoduje, iż on zawiesza pracę i dopiero przywrócenie go na pierwszy plan wznawia jego działanie :(


Ściskam prawicę, Jacek

http://doscniewoli.plPoznaj prawdę o pieniądzach
Free energy exists!

Offline

 

#5  2010-01-20 20:12:20

  bercik - Moderator Mamut

bercik
Moderator Mamut
Skąd: Warszawa
Zarejestrowany: 2006-09-23
Serwis

Re: [solved] Własny program uruchomiony w tle (oraz jego restart)

a jak go uruchamiasz w tle?


"Wszyscy wiedzą, że czegoś zrobić nie można. Ale przypadkowo znajduje się jakiś nieuk, który tego nie wie. I on właśnie robi odkrycie." (A.Einstein)

Offline

 

#6  2010-01-20 21:47:51

  Blackhole - Użytkownik

Blackhole
Użytkownik
Skąd: G. Śląsk
Zarejestrowany: 2005-09-07
Serwis

Re: [solved] Własny program uruchomiony w tle (oraz jego restart)

Zwyczajnie:

Kod:

./nazwa parametry &

Ściskam prawicę, Jacek

http://doscniewoli.plPoznaj prawdę o pieniądzach
Free energy exists!

Offline

 

#7  2010-01-20 22:36:38

  bercik - Moderator Mamut

bercik
Moderator Mamut
Skąd: Warszawa
Zarejestrowany: 2006-09-23
Serwis

Re: [solved] Własny program uruchomiony w tle (oraz jego restart)

a testowales na tym moim przykladzie? ... bo on po takim odpaleniu sie nie zatrzymywal tylko normalnie dzialal


"Wszyscy wiedzą, że czegoś zrobić nie można. Ale przypadkowo znajduje się jakiś nieuk, który tego nie wie. I on właśnie robi odkrycie." (A.Einstein)

Offline

 

#8  2010-01-21 09:10:20

  Blackhole - Użytkownik

Blackhole
Użytkownik
Skąd: G. Śląsk
Zarejestrowany: 2005-09-07
Serwis

Re: [solved] Własny program uruchomiony w tle (oraz jego restart)

Testowałem i działał, jak mówisz. Może masz jakieś przypuszczenie, dlaczego mój program nie działa w tle?


Ściskam prawicę, Jacek

http://doscniewoli.plPoznaj prawdę o pieniądzach
Free energy exists!

Offline

 

#9  2010-01-21 11:48:07

  Minio - Użyszkodnik

Minio
Użyszkodnik
Skąd: Poznań, Polska
Zarejestrowany: 2007-12-22
Serwis

Re: [solved] Własny program uruchomiony w tle (oraz jego restart)

A może podaj cały kod źródłowy swojego programu?

Offline

 

#10  2010-01-21 13:20:44

  Blackhole - Użytkownik

Blackhole
Użytkownik
Skąd: G. Śląsk
Zarejestrowany: 2005-09-07
Serwis

Re: [solved] Własny program uruchomiony w tle (oraz jego restart)

Hmm... Kod ma jakieś 4000 linii. Wrzucę więc tylko główną część (z main()):

Kod:

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <list>
#include <iostream>
#include "math.h"

#include <unistd.h>
#include <sys/stat.h>

#include <GL/freeglut.h>
#include <GL/glx.h>

#include <dirent.h>
#include <time.h>

list<char>        Decision;    // decyzja kojarzona z kaĹĽdym neuronem SOM
// (...)

int main(int argc, char **argv, char **envp) {
    int    no;
    system("clear");

    list<vec>::iterator xit;                    // iterator po wektorach x
    list<neuron>::iterator    nit;                    // iterator po neuronach

    if (argc<2)    goto JakUruchomic;
    for (i=1; i<argc; i++)
        if (arg_f(argc, argv, "-h")) {
        JakUruchomic:
            cout << "SposĂłb uruchamiania:\n";
            cout << argv[0] << " [-ms] [-ep] [-sx] [-s] [-t] [...]\n";
            return -2;
        }

//---------- przetworz parametry wejsciowe
    batch = arg_f(argc, argv, "-b");
    f_auto_classmap = arg_f(argc, argv, "-acm");
    teaching = arg_f(argc, argv, "-u");
    thinking = arg_f(argc, argv, "-m");
    testing = arg_f(argc, argv, "-t");
    backtest = arg_f(argc, argv, "-bt");
    f_background = arg_f(argc, argv, "-bg");  // będzie część działająca w tle
    colours = arg_f(argc, argv, "-k");
    normalize = arg_f(argc, argv, "-norm");
    f_loadnet = arg_f(argc, argv, "-ln");
    f_cron = arg_f(argc, argv, "-cron");    // uruchomienie z CRON'a
    f_debug_proc = arg_f(argc, argv, "-dproc");
    f_debug_pos = arg_f(argc, argv, "-dpos");
    f_debug_var = arg_f(argc, argv, "-dvar");
    f_debug = arg_f(argc, argv, "-debug");
    for (i=1; i<argc; i++)
        if (argv[i][0]=='-' && argv[i][1]=='p')
            Pair.assign(argv[i+1]);
//-----
    if (!thinking || !f_background || f_show)        InitOpenGL(argc, argv);

    if ((!thinking && select_x) || f_show) {
        CreateNeurons();

        cout << "P=" << P << "  N=" << N << "  K=" << K << endl;
        cout << endl;
        display();
    }
    if (!thinking && select_x)        glutMainLoop();

//-----------------------------------
    if (teaching)    {
        CreateNeurons();
        GetInputDataTeach();
        Teach();
        SaveNet();
    }
//-----------------------------------
    else if (f_background) {                                                                   // ***TUTAJ***
        cout << "Working in background..." << endl;
        string log;
        struct stat attrib;
        stat(argv[0], &attrib);
        int last_compile;
        last_compile = attrib.st_mtime;
        LoadNet();
        do {
            vec vec_in = GetInVector();            // odczytaj wektor wejściowy i czas jego tworzenia
            
            if (NNtime!=GetControlTime()) {            // jesli czas się zmienił, to niech sieć przetworzy dane i zwróci wynik
                i_BMU winner = Run(vec_in);
                plik_out.assign("out/");
                plik_out.append(Pair);
                plik_out.append(".out");
                FILE *fo = fopen(plik_out.c_str(), "wb");
                // zapisz wskaznik czasu, aby strategia NN wiedziala, czy siec zwrocila dane
                sprintf(c_txt, "%d\n", time(NULL));
                fputs(c_txt, fo);

                // zapisz wynik sieci
                sprintf(c_txt, "%d:%d_%s", winner.x,winner.y, getClusterNo(winner.x,winner.y).c_str());
                fputs(c_txt, fo);
                
                list<char>::iterator        Dit;
                Dit = Decision.begin();
                advance(Dit, mapsize_x*winner.y + winner.x);
                char decision[2];
                sprintf(decision, "%c", *Dit);
                fputs(decision, fo);
                
                fclose(fo);

                PutControlTime(NNtime);        // zapisz nowy czas kontrolny

                // zapisz wynik w logach
                log.assign(rpad(NNtime," ",12));
                log.append(c_txt);
                
                log.append(decision);
                
                log.append("\n");
                SaveLog(log);
            }
            usleep(200000);

            stat(argv[0], &attrib);
            if (last_compile != attrib.st_mtime) {
                log.assign("Restart");
                log.append("\n");
                SaveLog(log);
                execl(argv[0], argv[0], argv[1], argv[2], argv[3], 0);
            }

        } while(true);
    }

    return 0;
}

Cześć, która uruchamiana jest wtedy, gdy chcę, by program działał w tle, to fragment oznaczony przez ***TUTAJ***.


Ściskam prawicę, Jacek

http://doscniewoli.plPoznaj prawdę o pieniądzach
Free energy exists!

Offline

 

#11  2010-01-21 15:13:36

  bercik - Moderator Mamut

bercik
Moderator Mamut
Skąd: Warszawa
Zarejestrowany: 2006-09-23
Serwis

Re: [solved] Własny program uruchomiony w tle (oraz jego restart)

sproboj moze powstawiac w rozne miejsca tego programu jakies wypisywanie i zobaczyc na ktorym miejscu sie zawiesza gdy jest odpalany w tle ...

BTW przy sporym programie majacym opcje do uruchamiania w tle lepiej/ladniej aby wtedy program sam z siebie przechodzil w tlo ...


"Wszyscy wiedzą, że czegoś zrobić nie można. Ale przypadkowo znajduje się jakiś nieuk, który tego nie wie. I on właśnie robi odkrycie." (A.Einstein)

Offline

 

#12  2010-01-21 15:43:51

  Blackhole - Użytkownik

Blackhole
Użytkownik
Skąd: G. Śląsk
Zarejestrowany: 2005-09-07
Serwis

Re: [solved] Własny program uruchomiony w tle (oraz jego restart)

A jak programowo wymusić przejście do tła?


Ściskam prawicę, Jacek

http://doscniewoli.plPoznaj prawdę o pieniądzach
Free energy exists!

Offline

 

#13  2010-01-21 17:16:33

  bercik - Moderator Mamut

bercik
Moderator Mamut
Skąd: Warszawa
Zarejestrowany: 2006-09-23
Serwis

Re: [solved] Własny program uruchomiony w tle (oraz jego restart)

ponizszy kod pochodzi z zrodel wget i jest objety licencja GNU GPL:

Kod:

  pid = fork ();
  if (pid < 0)
    {
      /* parent, error */
      perror ("fork");
      exit (1);
    }
  else if (pid != 0)
    {
      /* parent, no error */
      printf (_("Continuing in background, pid %d.\n"), (int) pid);
      if (logfile_changed)
        printf (_("Output will be written to `%s'.\n"), opt.lfilename);
      exit (0);                 /* #### should we use _exit()? */
    }

  /* child: give up the privileges and keep running. */
  setsid ();
  freopen ("/dev/null", "r", stdin);
  freopen ("/dev/null", "w", stdout);
  freopen ("/dev/null", "w", stderr);

"Wszyscy wiedzą, że czegoś zrobić nie można. Ale przypadkowo znajduje się jakiś nieuk, który tego nie wie. I on właśnie robi odkrycie." (A.Einstein)

Offline

 

#14  2010-01-22 09:00:09

  Blackhole - Użytkownik

Blackhole
Użytkownik
Skąd: G. Śląsk
Zarejestrowany: 2005-09-07
Serwis

Re: [solved] Własny program uruchomiony w tle (oraz jego restart)

Dzięki za wskazówki! Skróciłem to, co podałeś do:

Kod:

    i=fork();
    if (i<0) exit(1); /* fork error */
    if (i>0) exit(0); /* parent exits */
    /* child (daemon) continues */

ze strony http://www.enderunix.org/documents/eng/daemon.php. Wydaje się działać wyśmienicie :) Po skompilowaniu każdy z procesów w tle (bo uruchamiam ich kilka) przeładowuje się przez execl i znów wchodzi w tło :) Tego potrzebowałem.


Ściskam prawicę, Jacek

http://doscniewoli.plPoznaj prawdę o pieniądzach
Free energy exists!

Offline

 

Stopka forum

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson
Nas ludzie lubią po prostu, a nie klikając w przyciski ;-)