我有一个必须使用Ctrl-C或SIGINT终止的进程。在这种情况下,我不能在键盘上使用Ctrl-C,因此必须在C中使用kill命令。 此代码基本上读取GPIO输入并启动和停止脚本record.sh,即GStreamer命令行脚本。
我只想终止在startVideoRecording()中创建的子进程。我需要按照我喜欢的方式多次开始,停止,开始,停止录制。这不是一次性的事情。
但是,当我更改gpio值并触发stopAllRecordings()时,它不会将SIGINT发送到子进程。只是挂在那里"向GStreamer进程发送中断..状态0"
如何确保使用Ctrl-C等效的视频录制过程终止?
感谢。
以下是代码:
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");
}
答案 0 :(得分:0)
您是否可能正在启动多个子进程并且只将SIGINT发送到您创建的最后一个子进程而不是之前的进程?输入“PS”并在启动此程序后按Enter键,查看已启动的进程数。
答案 1 :(得分:0)
我最终做到了这一点:
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");
}
它有效。
基本上,在创建AVRecordingProcess期间,我将其设置为进程组的头部。 发送进程组SIGINT还将其发送到组内的其余进程。 为了确保进程组结束,我使用了waitpid。
Linux专家,随时纠正我,谢谢!