prozess suspend resume auch unter linux...?
-
Hi,
ich erzeuge aus meinem Elternprozess mittles fork kinder nur möchte ich die Kinder synchonisiert was tun lassen.
Gruß
Franky
-
Du kannst die Signale
SIGSTOP
undSIGCONT
verwenden. (named) Semaphors funktioniert auch. Kommt halt darauf an, was du vor hast.
-
Hi,
danke für die Antwort! Zeigt das ich auf dem richtigen Weg bin.
Habe es zwischenzeitlich so gelöst...int main() { char buff[ MAX_BUFFER ], buff2[ MAX_BUFFER ], buff3[ MAX_BUFFER ]; int status; cout << "Ok, jetzt gehts los." << endl; while (1) { if( App1_pid == 0 ) { run_executable( App1_Pipe, App1path, App1_pid ); } if( App2_pid == 0 ) { run_executable( App2_Pipe, App2path, App2_pid ); kill( App2_pid, SIGSTOP ); } if( App3_pid == 0 ) { run_executable( App3_Pipe, App3path, App3_pid ); kill( App3_pid, SIGSTOP ); } int no_bytes = 0; bzero( buff, sizeof( buff ) ); if( App1_pid > 0 ){ read_pipebuffer( buff, no_bytes, PIPE_READ_END(App1_Pipe.pipe_stdout.pipe_fd) ); } if( no_bytes > 0 ){ printf("%s\n", buff); char *pWord = NULL; pWord = strstr( buff, "******Ready App1"); if(pWord){ kill( App2_pid, SIGCONT ); kill( App1_pid, SIGSTOP ); } pWord = NULL; } no_bytes = 0; bzero( buff2, sizeof( buff2 ) ); if( App2_pid > 0 ){ read_pipebuffer( buff2, no_bytes, PIPE_READ_END(App2_Pipe.pipe_stdout.pipe_fd) ); } if( no_bytes > 0 ){ printf("%s\n", buff2); char *pWord = NULL; pWord = strstr( buff2, "******Ready App2"); if(pWord){ kill( App2_pid, SIGSTOP ); kill( App3_pid, SIGCONT ); } pWord = NULL; } no_bytes = 0; bzero( buff3, sizeof( buff3 ) ); if( App3_pid > 0 ){ read_pipebuffer( buff3, no_bytes, PIPE_READ_END(App3_Pipe.pipe_stdout.pipe_fd) ); } if( no_bytes > 0 ){ printf("%s\n", buff3); char *pWord = NULL; pWord = strstr( buff3, "******Ready App3"); if(pWord){ kill( App3_pid, SIGSTOP ); kill( App1_pid, SIGCONT ); } pWord = NULL; } } return 0; }
App1, App2 als auch App3 haben eine while(1), sonst müsste ich waitpid machen um den Zombie zu erlösen.
Was ich damit bezecke? Ich habe drei Kindprozesse, die ich in der richtigen Reihenfolge laufen lassen will.
Gruß
Franky
-
-
Hi,
danke für den Link. Aber die Frage die ich mir stelle ist, ob die Lösung (Schnellschuß aus der Hüfte) schlecht ist? Die Tools sollen jedenfalls nicht mitbekommen das sie überwacht werden (ausser der ****ready... Mitteilungen)
Gruß
-
FrankTheFox schrieb:
Was ich damit bezecke? Ich habe drei Kindprozesse, die ich in der richtigen Reihenfolge laufen lassen will.
Was definierst du als "richtige" Reihenfolge? Durch das, was du da tust, wird gar keine Reihenfolge festgelegt, da die Zeit vom
SIGSTOP
bis zumSIGCONT
immer unterschiedlich ist. Die Programme laufen also unterschiedlich weit. Also Synchronisieren, tust du da garnichts.Falls du nur die Ausgabe synchronisieren willst, kann musst du die Prozesse dafür nicht einschlafen lassen. Ein Prozess wird eh so lange schlafen gelegt, bis seine Ausgabe ausgegeben wurde.
-
Hi,
ich wollte App1 dann App2 dann App3 startem. Wobei App2 und App3 sofort gestoppt werden. Also nur App1 laüft dann App1 laufen bis App1 "sagt" ******Ready App1, dann App1 stoppen und dananch App2. Mit App2 das gleiche tun: auf App2 warten bis ******Ready App2, dananch App3 ...
Das soll meine Reihenfolge sein. App1, App2, App2 laufen solage bis der Vater beendet wird.Wenn also in der Testanwendung App1 vor App2 vor App3 und danach wieder App1... nur zufällig richtig ist, wie kann ich das denn sonst machen?
Gruß
Franky
-
Hi,
ich habe den Code jetzt umgeschrieben...
#include <sys/wait.h> #define PIPE_READ_END(x) x[0] #define PIPE_WRITE_END(x) x[1] typedef enum{ acc_read = 0, acc_write = 1 } pipe_access_type; #define MAX_PIPE_FD 2 #define MAX_BUFFER 257 typedef enum{ exited, killed, stopped, continued, undefined } process_status_type; typedef struct { int pipe_fd[ MAX_PIPE_FD ]; int fnctl_flags [ MAX_PIPE_FD ]; pipe_access_type pipe_access; } pipe_stdin_type, pipe_stdout_type, pipe_stderr_type; typedef struct{ pipe_stderr_type pipe_stderr; pipe_stdin_type pipe_stdin; pipe_stdout_type pipe_stdout; } pipe_type; int run_executable( pipe_type &child_pipe, const char* progname, int &child_pid ); int read_pipebuffer( char* buff, int &no_bytes, int pipe_fd ); int monitor_child( const int &cpid, process_status_type &status); int child_response(const char* response, pipe_type const &App_Pipe, int const &App_pid );
und ...
... int App1_pid = 0; int App2_pid = 0; int App3_pid = 0; const char* App1path = "/home/frank/workspace/App1/App1"; const char* App2path = "/home/frank/workspace/App2/App2"; const char* App3path = "/home/frank/workspace/App3/App3"; const char* App1_response = "******Ready App1"; const char* App2_response = "******Ready App2"; const char* App3_response = "******Ready App3"; pipe_type App1_Pipe; pipe_type App2_Pipe; pipe_type App3_Pipe; int child_response(const char* response, pipe_type const &App_Pipe, int const &App_pid ){ char buff[ MAX_BUFFER ]; int no_bytes = 0; bzero( buff, sizeof( buff ) ); if( App_pid > 0 ){ read_pipebuffer( buff, no_bytes, PIPE_READ_END(App_Pipe.pipe_stdout.pipe_fd) ); } if( no_bytes > 0 ){ printf("%s\n", buff); char *pWord = NULL; pWord = strstr( buff, response); if(pWord){ return 1; } } return 0; } int monitor_child( const int &cpid, process_status_type &proc_status){ pid_t w; int status; do { w = waitpid(cpid, &status, WUNTRACED | WCONTINUED); if (w == -1) { perror("waitpid"); return -1; } if (WIFEXITED(status)){ proc_status == exited; //printf("exited, status=%d\n", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { proc_status == killed; //printf("killed by signal %d\n", WTERMSIG(status)); } else if (WIFSTOPPED(status)) { proc_status = stopped; //printf("stopped by signal %d\n", WSTOPSIG(status)); break; } else if (WIFCONTINUED(status)) { proc_status = continued; //printf("continued\n"); break; } } while (!WIFEXITED(status) && !WIFSIGNALED(status)); return 0; } int run_executable( pipe_type &child_pipe, const char* progname, int &child_pid ) { if( pipe( child_pipe.pipe_stdin.pipe_fd ) == -1) { perror( "pipe" ); } //init stdin stream PIPE_READ_END( child_pipe.pipe_stdin.fnctl_flags ) = fcntl( PIPE_READ_END( child_pipe.pipe_stdin.pipe_fd ), F_GETFL ); fcntl( PIPE_READ_END( child_pipe.pipe_stdin.fnctl_flags ), F_SETFL, PIPE_READ_END( child_pipe.pipe_stdin.fnctl_flags ) | O_NONBLOCK ); if( pipe( child_pipe.pipe_stdout.pipe_fd ) == -1) { perror( "pipe" ); } //init stdout stream PIPE_READ_END( child_pipe.pipe_stdout.fnctl_flags ) = fcntl( PIPE_READ_END( child_pipe.pipe_stdout.pipe_fd ), F_GETFL ); fcntl( PIPE_READ_END( child_pipe.pipe_stdout.fnctl_flags ), F_SETFL, PIPE_READ_END( child_pipe.pipe_stdout.fnctl_flags ) | O_NONBLOCK ); if( pipe( child_pipe.pipe_stderr.pipe_fd ) == -1) { perror( "pipe" ); } //init stderr stream PIPE_READ_END( child_pipe.pipe_stderr.fnctl_flags ) = fcntl( PIPE_READ_END( child_pipe.pipe_stderr.pipe_fd ), F_GETFL ); fcntl( PIPE_READ_END( child_pipe.pipe_stderr.fnctl_flags ), F_SETFL, PIPE_READ_END( child_pipe.pipe_stderr.fnctl_flags ) | O_NONBLOCK ); int pid = vfork(); if( pid == -1 ) { perror("fork"); exit( EXIT_FAILURE ); } else if(pid == 0){ child_pid = getpid(); close( PIPE_WRITE_END( child_pipe.pipe_stdin.pipe_fd ) ); close( PIPE_READ_END( child_pipe.pipe_stdout.pipe_fd ) ); close( PIPE_READ_END( child_pipe.pipe_stderr.pipe_fd ) ); dup2( PIPE_READ_END( child_pipe.pipe_stdin.pipe_fd ), STDIN_FILENO ); dup2( PIPE_WRITE_END( child_pipe.pipe_stdout.pipe_fd ), STDOUT_FILENO ); dup2( PIPE_WRITE_END( child_pipe.pipe_stderr.pipe_fd ), STDERR_FILENO ); execl( progname, progname, (char*) 0 ); _exit(1); } else if( pid > 0 ){ close( PIPE_READ_END( child_pipe.pipe_stdin.pipe_fd ) ); close( PIPE_WRITE_END( child_pipe.pipe_stdout.pipe_fd ) ); close( PIPE_WRITE_END( child_pipe.pipe_stderr.pipe_fd ) ); } return 0; } int read_pipebuffer( char* buff, int &no_bytes, int pipe_fd ) { char tmpBuff[ MAX_BUFFER ] = {0}; int i; size_t bytesread = 0; fd_set fds; struct timeval tv; tv.tv_sec = tv.tv_usec = 1; FD_ZERO( &fds ); FD_SET( pipe_fd, &fds); int rv = select( pipe_fd + 1, &fds, NULL, NULL, &tv ); if( rv == -1 ) perror("select"); else if ( rv > 0 ){ if( FD_ISSET( pipe_fd, &fds ) ) { bytesread = read( pipe_fd, tmpBuff, sizeof( tmpBuff ) ); no_bytes = bytesread; if( bytesread == 0 ) { return -1; } } } if(bytesread > 0 ){ if( strlen( tmpBuff ) > 0 ){ sprintf( buff, "%s", tmpBuff ); tmpBuff[ MAX_BUFFER ] = 0; } } FD_CLR( pipe_fd, &fds ); return 0; } int main() { char buff[ MAX_BUFFER ], buff2[ MAX_BUFFER ], buff3[ MAX_BUFFER ]; int status; cout << "Ok, jetzt gehts los." << endl; process_status_type proc_status; int App1_stopped = 1, App2_stopped = 1, App3_stopped = 1, App4_stopped = 1; while (1) { //run App1 while App2 & App3 stopped if( App1_pid == 0 && App1_stopped && App2_stopped && App3_stopped ) { run_executable( App1_Pipe, App1path, App1_pid ); App1_stopped = 0; } else if( App1_pid > 0 && ( App1_stopped && App2_stopped && App3_stopped ) ){ kill( App1_pid, SIGCONT ); App1_stopped = 0; } if ( child_response( App1_response, App1_Pipe, App1_pid ) ){ kill( App1_pid, SIGSTOP ); proc_status = undefined; monitor_child( App1_pid, proc_status ); if( proc_status == stopped ) {App1_stopped = 1;} } //run App2 while App1 & App3 stopped... if( App2_pid == 0 && ( App1_stopped && App2_stopped && App3_stopped ) ) { run_executable( App2_Pipe, App2path, App2_pid ); App2_stopped = 0; } else if( App2_pid > 0 && App1_stopped && App2_stopped && App3_stopped ){ kill( App2_pid, SIGCONT ); App2_stopped = 0; } if ( child_response( App2_response, App2_Pipe, App2_pid ) ){ kill( App2_pid, SIGSTOP ); proc_status = undefined; monitor_child( App2_pid, proc_status ); if( proc_status == stopped ) App2_stopped = 1; } //run App3 while App2 & App1 stopped... if( App3_pid == 0 && (App1_stopped && App2_stopped && App3_stopped ) ) { run_executable( App3_Pipe, App3path, App3_pid ); App3_stopped = 0; } else if( App3_pid > 0 && ( App3_stopped && App2_stopped && App1_stopped ) ){ kill( App3_pid, SIGCONT ); App3_stopped = 0; } if ( child_response( App3_response, App3_Pipe, App3_pid ) ){ kill( App3_pid, SIGSTOP ); proc_status = undefined; monitor_child( App3_pid, proc_status ); if( proc_status == stopped ) App3_stopped = 1; } } return 0; }
bin ich jetzt näher an meiner Reihenfolge dran?
Gruß