2017-04-19 21 views
1

数日前、私はhereにfork()を使わずにCを使ってプログラムを起動する方法を尋ねました。この解決策はうまくいきます...私はこの子プロセスを殺すことができません! 私のプログラム(この場合は 'rbfeeder')にはいくつかのスレッドがあります....そして、killシグナルを送信すると、スレッドだけが強制終了されます(私は思う)。私は間違って何をしていますか?spawnで起動したPIDをkillできません

これは、 'スタート' rbfeederに使用されるコードです:

/* 
* Start dump1090, if not running 
*/ 
void startDump(void) { 

    if (p_dump != 0) { 
     log_level(8, "Looks like dump is already running.\n"); 
     return; 
    } 

    pid_t ret = run_cmd("/home/jmaurin/dev/client/rbfeeder"); 

    if (ret != 0) { 
     log_level(8, "Ok, started! Pid is: %i\n", ret); 
     p_dump = ret; 
     sendStats(); 
    } else { 
     log_level(8, "Error starting dump1090\n"); 
     p_dump = 0; 
     sendStats(); 
    } 

    return; 
} 

そして、これが 'STOP' にコードです:

void stopDump(void) { 

    if (checkDumpRunning()) { 
     log_level(3, "Dump is running, let's try to kill.\n"); 

     if (kill(p_dump, SIGKILL) == 0) { 
      log_level(3,"Succesfull kill dump!\n"); 
      sendStats(); 
      return; 
     } else { 
      log_level(3,"Error killing dump.\n"); 
      return; 
     } 


    } else { 
     log_level(3, "Dump is not running.\n"); 
    } 

    return; 
} 

とrun_cmd機能:

pid_t run_cmd(char *cmd) { 
    pid_t pid, ret; 
    char *argv[] = {"sh", "-c", cmd, NULL}; 
    int status, s; 
    posix_spawn_file_actions_t file_actions; 
    posix_spawn_file_actions_t *file_actionsp; 

    s = posix_spawn_file_actions_init(&file_actions); 
    if (s != 0) 
     return 0; 

    //STDERR_FILENO 
    s = posix_spawn_file_actions_addclose(&file_actions,STDERR_FILENO); 
    if (s != 0) 
     return 0; 

    file_actionsp = &file_actions; 


    //printf("Run command: %s\n", cmd); 
    status = posix_spawn(&pid, "/bin/sh", file_actionsp, NULL, argv, environ); 
    if (status == 0) { 
     log_level(8, "Child pid: %i\n", pid); 
     ret = pid; 
     /*   
     if (waitpid(pid, &status, 0) != -1) { 
      printf("Child exited with status %i\n", status); 
     } else { 
      perror("waitpid"); 
     } 
     */ 
    } else { 
     // printf("posix_spawn: %s\n", strerror(status));   
     ret = 0; 
    } 

    return ret; 
    //printf("End of run\n"); 
} 

p_dumpはPIDを保持するグローバル変数です。私のクライアントは、 "外部プログラムを起動する(オーバーイーサネット)コマンドを受信したとき

この画像は次のとおりです。

enter image description here

その後、同じマシン上のホテルトップ.... PIDがあることがわかり私の変数が正しいことを意味し、同じ:

enter image description here

をその後、私は「停止」コマンドを送信したと私のクライアントは、実行「stopDump」が、1つのプロセスは同じプログラムから(他のスレッドを実行していますar E '殺し'):

enter image description here

外部プログラムは '産卵/フォーク' 自体はありませんが、スレッドを持っています。

答えて

0

user1937198の回答はうまくいきましたが、「waitpid」のような関数を呼び出す必要のない別の方法が見つかりました。

struct sigaction sigchld_action = { 
    .sa_handler = SIG_DFL, 
    .sa_flags = SA_NOCLDWAIT 
}; 
sigaction(SIGCHLD, &sigchld_action, NULL); 

私の場合、少なくとも、殺した後はゾンビの処理を妨げています。それはうまく動作します。

3

プロセスがゾンビ(HTOPのステータス列のZ)になっているため、処理が正常に完了しています。ゾンビとは、カーネル内にメタデータが残っているが、実際には実行されていないプロセスです。ゾンビを取り除くために、親はその過程を待たなければならない。あなたのプロセスが親プロセスなので、killが成功した後にwaitpid(p_dump)への呼び出しを追加すると、これが処理されます。

+0

は何も変わっていません:('' '場合(キル(p_dump、SIGKILL)== 0){ のwaitpid(p_dump); airnav_log_level(3、 "succesfullのキル・ダンプ\ nは!"); sendStats( ); リターン; }他{ airnav_log_level(3、 "エラー殺害ダンプする\ n"); リターン; } '' ' –

+0

JonisMaurinCeará@あなたが本当に' waitpidの(p_dump)を追加しました; '??? [ 'pid_t waitpid(pid_t pid、int * stat_loc、int options);'のように、RTFM](http://man7.org/linux/man-pages/man3/wait.3p.html) '答えも修正する必要があります。 –