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!
Prosimy o pomoc dla małej Julki — przekaż 1% podatku na Fundacji Dzieciom zdazyć z Pomocą.
Więcej informacji na dug.net.pl/pomagamy/.
Strony: 1
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)
Offline
u mnie dziala:
#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
./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)
Offline
Dzięki, bercik. Spróbuję to wykorzystać.
Offline
Załatwiłem tak przeładowywanie się po kompilacji:
// (...) // 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 :(
Offline
a jak go uruchamiasz w tle?
Offline
Zwyczajnie:
./nazwa parametry &
Offline
a testowales na tym moim przykladzie? ... bo on po takim odpaleniu sie nie zatrzymywal tylko normalnie dzialal
Offline
Testowałem i działał, jak mówisz. Może masz jakieś przypuszczenie, dlaczego mój program nie działa w tle?
Offline
A może podaj cały kod źródłowy swojego programu?
Offline
Hmm... Kod ma jakieś 4000 linii. Wrzucę więc tylko główną część (z main()):
#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***.
Offline
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 ...
Offline
A jak programowo wymusić przejście do tła?
Offline
ponizszy kod pochodzi z zrodel wget i jest objety licencja GNU GPL:
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);
Offline
Dzięki za wskazówki! Skróciłem to, co podałeś do:
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.
Offline
Strony: 1