2011-07-15 12 views
3

私はプロセスをチェックポイントするチェックポイント機能を実装しようとしています。私は子プロセスをフォークすることでそれを行います。しかし、私は開始時に子プロセスを一時停止する必要があります。後で、チェックポイントから再起動するには、子プロセスを一時停止し、親プロセスを終了させることができます。開始時に子プロセスを停止する

ここでは、私がcheckpointrestart_from_checkpointのために書いたコードと、それを呼び出す方法の例を示します。

#include <stdio.h> 
#include <unistd.h> 
#include <sys/ptrace.h> 
#include <sys/wait.h> 

pid_t checkpoint(); 
void restart_from_checkpoint(pid_t pid); 

int main(int argc, char *argv[]) 
{ 
    int i; 
    pid_t child_pid; 
    pid_t parent_pid = getpid(); 

    for(i = 0; i < 10; i++) 
    { 
    if (i == 4) 
    { 
     printf("%6s: Checkpointing!\n", (getpid() == parent_pid)? "parent":"child"); 
     child_pid = checkpoint(); 
    } 

    if (i == 7) 
    { 
     printf("%6s: Restarting!\n", (getpid() == parent_pid)? "parent":"child"); 
     restart_from_checkpoint(child_pid); 
    } 

    printf("%6s: i = %d\n", (getpid() == parent_pid)? "parent":"child", i); 
    } 

    return 0; 
} 

pid_t checkpoint() 
{ 
    pid_t pid; 
    int wait_val; 

    switch (pid=fork()) 
    { 
    case -1: 
     perror("fork"); 
     break; 
    case 0:   // child process starts 
     ptrace(PTRACE_TRACEME,0,0,0); 
     raise(SIGTRAP); // Note that this is the solution to first part 
           // of the question, which I added after 
           // asking this question. 
     break; // child process ends 
    default:  // parent process starts 
     wait(&wait_val); 
     return pid; 
    } 
} 

void restart_from_checkpoint(pid_t pid) 
{ 
    ptrace(PTRACE_CONT, pid, NULL, NULL); 
    wait(NULL); // I'm just waiting here, but actually 
       // I need to kill the calling process. 
} 

ptrace(PTRACE_TRACEME,0,0,0)を呼び出した後、子プロセスを停止する方法がわかりません。第二に、私は子供がrestart_from_checkpointで続けることを許しながら、親プロセスを殺す方法を知らない。

ptraceのパラメータを使用すると、フォークされたプロセスが最初に停止し、後でPTRACE_CONTで開始される可能性があります。残念なことに、PTRACE_TRACEMEはexec関数呼び出しでのみ停止します。

+0

これで、ptrace(PTRACE_TRACEME、0、0、0)の直後にraise(SIGTRAP)を発行することで、部分的に正しいとしました。今度は、restart_from_checkpointを呼び出して親プロセスを終了するだけです。 – MetallicPriest

+0

CまたはC++でコンパイルしていますか?私はここにCコードしか見ません。 – Puppy

+0

私はCまたはC++を使用していても問題ありませんか? – MetallicPriest

答えて

0

OK、私は解決策を見つけました。その作業は完璧です。興味のある人のためのコードはここにあります。

#include <stdio.h> 
#include <unistd.h> 
#include <sys/ptrace.h> 
#include <sys/wait.h> 
#include <stdlib.h> 

pid_t checkpoint(); 
void restart_from_checkpoint(pid_t pid); 

int main(int argc, char *argv[]) 
{ 
    int i; 
    pid_t child_pid; 
    pid_t parent_pid = getpid(); 

    for(i = 0; i < 10; i++) 
    { 
    if (i == 4) 
    { 
     printf("%6s: Checkpointing!\n", (getpid() == parent_pid)? "parent":"child"); 
     child_pid = checkpoint(); 
    } 

    if (i == 7 && (getpid() == parent_pid)) 
    { 
     printf("%6s: Restarting!\n", (getpid() == parent_pid)? "parent":"child"); 
     restart_from_checkpoint(child_pid); 
    } 

    printf("%6s: i = %d\n", (getpid() == parent_pid)? "parent":"child", i); 
    } 

    return 0; 
} 

pid_t checkpoint() 
{ 
    pid_t pid; 
    int wait_val; 

    switch (pid=fork()) 
    { 
    case -1: 
     perror("fork"); 
     break; 
    case 0:   // child process starts 
     ptrace(PTRACE_TRACEME,0,0,0); 
     raise(SIGTRAP); 
     break; // child process ends 
    default:  // parent process starts 
     wait(&wait_val); 
     return pid; 
    } 
} 

void restart_from_checkpoint(pid_t pid) 
{ 
    ptrace(PTRACE_CONT, pid, NULL, NULL); 
    ptrace(PTRACE_DETACH, pid, NULL, NULL); 
    exit(1); 
} 
0

あなたはIPCセマフォまたはSIGNAL USR1を使用することができます...

+0

どのように?私はSIGUSR1とシグナルを使用しようとしましたが、運はありませんでした!少し詳しく説明したり、コードサンプルをいくつか表示できますか? – MetallicPriest

+0

最初にforkされたプロセスを停止し、後でPTRACE_CONTで開始するために使用できるptraceのパラメータはありますか。私はその行に沿って考えています。もしあれば、私は信号と混同する必要はありません! – MetallicPriest

+0

ptrace(PTRACE_TRACEME、0、0、0)の直後にraise(SIGTRAP)を呼び出して最初の部分を解決しました。 – MetallicPriest

関連する問題