Теперь я знаю, что эта проблема довольно распространена, но поверьте мне, я не знаю, почему происходит именно этот случай. ребенок. Я использую dup2
в child1, чтобы дублировать стандартный вывод с файлом logfile
. Я ожидаю, что оба ребенка будут записывать все сообщения в этот файл.
Вот псевдокод моего приложения.
fork();
if(child1){
// child 1 operations
int log_fd = open(logfile, O_CREAT | O_APPEND | O_WRONLY, S_IRUSR | S_IWUSR);
dup2(log_fd, 1);
fork();
if(child2){
// child 2 operations
execvp(executable, params);
}
else {
int status;
wait(&status);
// child 1 more operations
}
}
else{
// parent operations
}
return 0;
Итак, это суть того, что происходит в моем приложении. code, исходный код немного велик для совместного использования.
Вот тестовая программа для executable
, которая запускается execvp
.
#include <iostream>
#include <unistd.h>
int main(int argc, char const *argv[]) {
// setvbuf(stdout, NULL, _IONBF, 0);
printf("pf: started test process\n");
// std::cout << "co: started test process" << std::endl;
uint32_t timer = 1;
while(true){
// std::cout << "co: tick tick " << timer++ << std::endl;
printf("pf: tick tick %u\n", timer++);
// fflush(stdout);
sleep(1);
}
return 0;
}
Проблема в том, что ни один из операторов printf
не появляется в logfile
. Однако, как вы можете видеть комментируемые операторы, такие как 'cout', 'fflu sh' или 'setvbuf', сообщения печати начинают появляться в logfile
. Я не понимаю, почему операторы printf
не сбрасывают буфер.
Еще меня беспокоит то, что операторы printf в child 1 operations
и child 2 operations
в моем псевдокоде приложения работают нормально. Только программа, запущенная execvp
, вызывает проблемы. Но почему?!
Дополнительная информация
Это была тестовая программа, которую я написал, чтобы проверить, будет ли мой logi c работать перед фактической разработкой приложения.
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, char const *argv[]){
const char* name = "/Users/molecule/tp/cpp/output.log";
char *const args[] = {"ls", NULL};
int status;
printf("start\n");
if (fork() == 0){
printf("child\n");
int fd = open(name, O_CREAT | O_APPEND | O_WRONLY, S_IRUSR | S_IWUSR);
printf("fd %d\n", fd);
dup2(fd, 1);
printf("child after dup2\n");
if(fork() == 0){
printf("child2\n");
execvp(args[0], args);
close(fd);
exit(0);
}
}
else {
wait(&status);
printf("status %d\n", status);
}
return 0;
}
Это работает отлично. Результат ls
можно увидеть в файле output.log
. Но я не могу понять, что не так в моем приложении. Пожалуйста, помогите мне в этот мучительный момент.