5

メインプログラムで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ブロック」に戻ってプログラムを続行します。

4

3 に答える 3

11

次のことを行う必要があります。

  1. 最初に ) を実行しますkill(pid, SIGTERM。これにより、子プロセスが正常に終了する機会が与えられます。
  2. しばらく待ちます ( を使用sleep)。この時間は、子プロセスが正常に終了するまでにかかる時間によって異なります。
  3. waitpid(pid, &status, WNOHANG)戻り値を確認して使用します。プロセスが中止されていない場合は、手順 4 を実行します。
  4. a kill(pid, SIGKILL) を実行し、次に を実行してゾンビを収穫しwaitpid(pid, &status, 0)ます。

これらの手順により、子プロセスが終了するシグナル ハンドラーを持つようになり、ゾンビ プロセスがなくなることも保証されます。

于 2013-01-01T13:29:53.233 に答える
1

POSIXは、これに対するkill(2)システムコールを定義します。

kill(pid, SIGKILL);
于 2013-01-01T13:11:59.197 に答える
1

プログラムの内外を問わず、を使用することができますkill。を含める<signal.h>ことで、特定の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);
}

killシェルでコマンドを使用することもできます。子プロセスのPIDを見つけるには、psコマンドを実行します。

man kill
関数は 、kill()pidで指定されたプロセスまたはプロセスのグループにシグナルを送信します。送信する信号はsigで指定され、リストの1つ<signal.h>または0のいずれかです。sigが0(ヌル信号)の場合、エラーチェックは実行されますが、実際には信号は送信されません。nullシグナルは、pidの有効性をチェックするために使用できます。

于 2013-01-01T13:12:14.200 に答える