简体   繁体   English

无法终止分叉过程

[英]Unable to terminate forked process

I have a process which has to be terminated using Ctrl-C or SIGINT. 我有一个必须使用Ctrl-C或SIGINT终止的过程。 In this case I cannot use Ctrl-C physically with the keyboard, so it has to done using a kill command in C. This code basically reads GPIO input and starts and stops a script record.sh , a GStreamer command line script. 在这种情况下,我无法在键盘上实际使用Ctrl-C,因此必须使用C中的kill命令来完成。此代码基本上读取GPIO输入,并启动和停止脚本record.sh(GStreamer命令行脚本)。

I only want to terminate the child process created in startVideoRecording(). 我只想终止在startVideoRecording()中创建的子进程。 I need to do start, stop, start, stop the recording as many times as I like. 我需要根据需要多次开始,停止,开始,停止录制。 It's not a one-off thing. 这不是一次性的事情。

However, when I change the gpio value and trigger stopAllRecordings(), it doesn't send the SIGINT to the child process. 但是,当我更改gpio值并触发stopAllRecordings()时,它不会将SIGINT发送给子进程。 It just hangs there at "Sending interrupt to GStreamer process.. Status 0" 它只是挂在“向GStreamer进程发送中断。状态0”处。

How can I make sure that the video recording process is terminated with a Ctrl-C equivalent? 如何确保视频录制过程以Ctrl-C等效项终止?

Thanks. 谢谢。

Here's the code : 这是代码:

int main() {
    pollGPIOSwitch(&vn200);
}


void* pollGPIOSwitch(void* arg) {


   Vn200* vn200 = (Vn200*)arg;
   int fd;
   char buf[100];
   char value; 
   int videoRecError;
   bool videoRecOn = false;

   sprintf(buf, "/sys/class/gpio/gpio56/value");

   while (KEEP_GOING) {
       fd = open(buf,O_RDONLY);
       lseek(fd,0,SEEK_SET); // move to beginning of file
       read(fd,&value,1);
       if (value=='0') {
           if (videoRecOn) { // recording on, switch off, end recording
               stopAllRecordings();
               videoRecOn = false;
               TriggerGPSINSThreadExit = 0; // reset variables
               printf("Reset GPSINS Thread variables.\n");
           }
       }
       else if (!videoRecOn) { // recording off, switch on, start recording
            if (pthread_create(&GPSINSLoggingThread, NULL, runGPSINS,(void*) vn200) != 0) {
                printf("Error: Fail to create runGPSINS thread\n");
            }

            videoRecError = startVideoRecording();
            if (videoRecError == -1)
                pthread_exit(&videoRecError);
            videoRecOn = true; 
       }
       usleep(500000);
   }
   close(fd);


   printf("Exited Polling!");
}

int startVideoRecording() {
    int error;
    error = 0;

    if ((AVRecordingProcess = fork()) != -1) {
        switch (AVRecordingProcess) {
            case -1:
                printf("Error: Fail to create AVRecordingProcess\n");
                error = -1;
            case 0:
                execl("record.sh", "0", NULL);
                //system("//root//record.sh");
                printf("Error: Fail to execute AVRecordingProcess\n");
                error = -1;
            default:
               printf("Video Recording...process id %d\n", AVRecordingProcess); 
                break;
        }
    } else {  
        printf("Error: MainHost failed to fork AVRecordingProcess\n");
        error = -1;
    } 

    return error;

}


void stopAllRecordings() {
    int ret; 
    FILE *infile, *outfile;
    int ch;


    printf("Terminating child processes..%d\n", AVRecordingProcess);
    ret = kill(AVRecordingProcess, SIGINT);
    printf("Sending interrupt to GStreamer process.. Status %d\n", ret);

    int status;
    printf("Wait for the GStreamer process %d to end....", AVRecordingProcess);
    wait(AVRecordingProcess);
    printf("GStreamer ended.\n"); 
}

Is it possible that you are starting multiple child processes and only sending SIGINT to the last child process you created and not earlier ones? 您是否有可能启动多个子进程,并且仅将SIGINT发送到您创建的最后一个子进程,而不是之前的进程? Type 'PS' and hit enter after starting this program and see how many processes you have started. 键入“ PS”,然后在启动该程序后按Enter键,查看已启动了多少个进程。

I eventually did this : 我最终做到了:

int startVideoRecording() {
    int error;
    error = 0;

    if ((AVRecordingProcess = fork()) != -1) {
        switch (AVRecordingProcess) {
            case -1:
                printf("Error: Fail to create AVRecordingProcess\n");
                error = -1;
            case 0:
                setpgid(AVRecordingProcess,0);  <-- NEW
                execl("record.sh", "0", NULL);
                //system("//root//record.sh");
                printf("Error: Fail to execute AVRecordingProcess\n");
                error = -1;
            default:
               printf("Video Recording...process id %d\n", AVRecordingProcess); 
                break;
        }
    } else {  
        printf("Error: MainHost failed to fork AVRecordingProcess\n");
        error = -1;
    } 

    return error;

}

void stopAllRecordings() {
    int ret; 
    FILE *infile, *outfile;
    int ch;


    printf("Terminating child processes..%d\n", AVRecordingProcess);
    ret = killpg(AVRecordingProcess, SIGINT); <-- NEW
    printf("Sending interrupt to GStreamer process.. Status %d\n", ret);

    int status;
    printf("Wait for the GStreamer process %d to end....", AVRecordingProcess);
    waitpid(AVRecordingProcess,0,0); <-- NEW
    printf("GStreamer ended.\n"); 
}

and it works. 而且有效。

Basically, during the creation of the AVRecordingProcess, I set it as the head of the process group. 基本上,在创建AVRecordingProcess的过程中,我将其设置为进程组的头。 Sending the process group SIGINT sends it also to the rest of the processes within the group. 发送进程组SIGINT也将其发送到组中的其余进程。 To make sure the process group ended, I used waitpid. 为了确保进程组结束,我使用了waitpid。

Linux experts, feel free to correct me, thanks! Linux专家,请随时指正我,谢谢!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM