【问题标题】:How to terminate a child process which is running another program by doing exec如何通过执行 exec 终止正在运行另一个程序的子进程
【发布时间】:2012-12-16 03:39:32
【问题描述】:

我正在我的主程序中执行 fork,并在子进程中执行 exec,这将运行另一个程序。现在我想终止子程序(即由 exec 调用的程序)并返回主程序(或父程序)。我怎么能做到这一点..我尝试使用 ctrl+c 但它也杀死了父进程和子进程。请帮助我。

/*This is main.c*/

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

void sig_int(void);
void sig_term(void);

pid_t pid,ppid;

int main(char argc,char **argv){

int n;
char ch;

printf("***********Application to start or stop services**********\n");

do
{
    printf("Enter 1 to start service no.1\n");
    printf("Enter 2 to start service no.2\n");
    printf("Enter 3 to start service no.3\n");

    scanf("%d",&n);
    if(fork() == 0)
    {
        switch(n)
        {
            case 1: printf("starting service no. 1..\n");
                printf("checking whether the given service is     already running...\n");
            //  system("./det.sh ./test")   
                pid = getpid();
                printf("child process pid = %d\n",pid);
//                  signal(SIGINT,(void *)sig_int);
//                  signal(SIGTERM,(void *)sig_term);
                  //execl("/var/vR_main","vR_main",argv[1],argv[2],argv[3],argv[4],NULL);
                execl("./test","test",0,0);//will run test.c
                break;

            case 2: printf("starting service no. 2..\n");
                break;

            case 3: printf("starting service no. 3..\n");
                break; 

        }

    }
    else
    {   
        int status;
        wait(&status);  
            if (WIFEXITED(status))
                printf("CHILD exited with %d\n", WEXITSTATUS(status));

            if (WIFSIGNALED(status))
                printf("signaled by %d\n", WTERMSIG(status));

            if (WIFSTOPPED(status))      
                printf("stopped by %d\n", WSTOPSIG(status));
//          sleep(2);
        ppid = getpid();
        printf("%d\n",ppid);
//          wait();
        printf("\nDo you want to continue...y/n:");
        scanf(" %c",&ch);
    }
}while(ch == 'y');

return 0;   

}

void sig_int(void)
{
printf("caught signal\n");
kill(pid,SIGKILL);
//  signal(SIGINT,SIG_DFL);
//  exit(0);
}

void sig_term(void)
{
printf("killing the process\n");
signal(SIGINT,SIG_DFL);
//  exit(0);
}

/*This is test.c*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>

void sig_int(void);
void sig_term(void);

pid_t pid;
int main()
{
//  int a=10,b=40,c=50,max;

    pid = getpid();
printf("exec pid = %d\n",pid);

while (1)
{

    signal(SIGINT,(void *)sig_int);
    signal(SIGTERM,(void *)sig_term);
}
//  max=a>b?a>c?a:c:b>c?b:c;
//  printf("%d\n",max);
}
void sig_int(void)
{
printf("caught signal\n");
//  signal(SIGINT,SIG_DFL);
kill(pid,SIGKILL);
//  exit(0);

}

void sig_term(void)
{
printf("killing the process\n");
signal(SIGINT,SIG_DFL);
//  exit(0);
}

现在我想杀死“测试应用程序”(由exec调用),并返回父进程或“else块”继续程序。

【问题讨论】:

  • 看起来像这个问题:
  • 你说“回到主程序”,但是如果你fork,估计还在运行??

标签: c


【解决方案1】:

您需要执行以下操作:

  1. 首先执行kill(pid, SIGTERM) - 这使子进程有机会优雅地终止
  2. 等待一段时间(使用sleep)。时间段取决于子进程正常关闭所需的时间。
  3. 使用waitpid(pid, &amp;status, WNOHANG)检查返回值。如果该过程尚未中止,请执行第 4 步
  4. 执行kill(pid, SIGKILL) 然后执行waitpid(pid, &amp;status, 0) 收割僵尸。

这些步骤确保您让子进程有一个信号处理程序来关闭,并确保您没有僵尸进程。

【讨论】:

    【解决方案2】:

    无论是在程序内部还是外部,都可以使用kill。通过包含&lt;signal.h&gt;,您可以终止具有给定PID 的进程(使用fork 返回值来执行此操作)。

    #include <signal.h>
    
    int pid;
    
    switch (pid = fork())
    {
    case -1:
      /* some stuff */
      break;
    case 0: 
      /* some stuff */
      break;
    default:
      /* some stuff */
      kill(pid, SIGTERM);
    }
    

    也可以在 shell 中使用kill 命令。要查找您的子进程的PID,您可以运行ps 命令。

    人杀
    kill() 函数应向 pid 指定的一个进程或一组进程发送信号。要发送的信号由 sig 指定,可以是&lt;signal.h&gt; 中给出的列表中的一个,也可以是 0。如果 sig 为 0(空信号),则执行错误检查,但实际上不发送任何信号。 null 信号可用于检查 pid 的有效性。

    【讨论】:

    • 当心fork返回-1
    【解决方案3】:

    POSIX 为此定义了kill(2) 系统调用:

    kill(pid, SIGKILL);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-07
      • 2010-11-30
      • 1970-01-01
      • 2023-03-30
      • 2013-05-27
      • 2021-07-26
      • 1970-01-01
      • 2015-01-18
      相关资源
      最近更新 更多