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

Użytkownik
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




Moderator Mamut
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

Użytkownik
Dzięki, bercik. Spróbuję to wykorzystać.
Offline

Użytkownik
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




Moderator Mamut
a jak go uruchamiasz w tle?
Offline

Użytkownik
Zwyczajnie:
./nazwa parametry &
Offline




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

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




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

Użytkownik
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




Moderator Mamut
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

Użytkownik
A jak programowo wymusić przejście do tła?
Offline




Moderator Mamut
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

Użytkownik
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