2011-07-15 49 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

现在我找到了部分的权利,通过发行募集(SIGTRAP),刚刚经过的ptrace(PTRACE_TRACEME,0,0,0)。现在我只需要父进程在调用restart_from_checkpoint时退出。 – MetallicPriest

+0

您是用C还是C++编译?我只在这里看到C代码。 – Puppy

+0

如果我使用C或C++,这无关紧要吗? – MetallicPriest

回答

0

好的,我找到了解决方案。它的工作现在完美。这里是你感兴趣的人的代码。

#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信号或信号USR1 ...

+0

如何?我试图使用SIGUSR1和信号,但没有运气!你能详细说明一下还是展示一些代码示例。 – MetallicPriest

+0

ptrace中是否有任何参数可用于在开始时停止分叉进程,并稍后以PTRACE_CONT开始。我正在考虑这一方面。如果有的话,我不需要混淆信号! – MetallicPriest

+0

通过在ptrace(PTRACE_TRACEME,0,0,0)之后调用raise(SIGTRAP)来解决第一部分。 – MetallicPriest