open () завершается неудачно с первой попытки - PullRequest
3 голосов
/ 31 января 2012

open() завершается неудачно с ENOENT (такого файла или каталога нет) с первой попытки, но прекрасно работает при последующих попытках.
Моя программа разветвляет дочерний процесс и ожидает, пока дочерний процесс завершит использование waitpid().Дочерний процесс создает копию пути к файлу, полученного от пользователя в определенном каталоге, используя execl().
. После выхода из дочернего процесса родительский процесс открывает эту вновь созданную копию, используя open().Однако он завершается неудачно с ENOENT (нет такого файла или каталога) с первой попытки.Я вижу, что дочерний процесс создает файл в указанном каталоге.
Если я снова запустите эту программу, указав то же имя файла, то он будет работать нормально.Мой вопрос: почему он не открывает файл с первой попытки?Нужно ли обновлять каталог или что это?

Я на Redhat

ЗДЕСЬ БЫСТРЫЙ ЗАГРЯЗНЕННЫЙ КОД ОТКРЫТКИ

my_function()
{
char *src = "TEST.txt";  
char *dest = "./Output/";  
char *fp = "/Output/TEST.txt";  
int fd;  
struct fstat file_stat;  

pid_t PID = fork();  

if(PID == -1)  
      exit(1);   


if(PID == 0)  
{
       execl("/bin/cp", "/bin/cp", src, dest);   
       exit(1);   
}   


if(PID > 0)  
{  
       int chldstat;
       pid_t ws = waitpid(PID,&chldstat,WNOHANG);  
}  


if(stat(fp,&file_stat) == -1)  
{  
       perror("stat");  
       exit(1);  
}  


if((fd = open(dest,O_RDWR)) == -1)  
{  
       perror("open");
       exit(1);
}  


if((fp=mmap(0,file_stat.st_size,PROT_READ | PROT_WRITE,fd,0)) == -1)  
{  
       perror("mmap");
       exit(1);
}  


//OTHER ROUTINES      
.............  
............    
............  


}  

Ответы [ 2 ]

3 голосов
/ 01 февраля 2012

Как уже отмечалось, трудно ответить на такой вопрос без исходного кода.Но:

Вы, похоже, страдаете от состояния гонки.Файл создан, но немного позже, чем ваша первая попытка открытия.Со второй попытки вам повезло, и файл уже был создан.
Тот факт, что повторный запуск работает нормально, подтверждает эту теорию - файл существовал еще до запуска программы, поэтому открытие его может быть успешным в любое время.

Почему у вас есть состояние гонки?Если ребенок создает его, а отец пытается открыть его только после того, как он проверит, что ребенок закончил, тогда не должно быть никаких проблем.
Трудно предположить, что пошло не так.Может быть, вы ждете неправильный процесс.Возможно, дочерний процесс создает другой процесс, который создает файл, а родительский ожидает только первого дочернего процесса.И миллион других майбов.

1 голос
/ 04 февраля 2012

Вы звоните waitpid() с флагом WNOHANG, что означает, что он фактически не будет блокировать ожидание дочернего элемента, если он все еще работает. Этот флаг используется для проверки, изменилось ли состояние дочернего процесса, фактически не ожидая его, если нет; возвращаемое значение укажет, был ли ребенок готов. Если вы хотите, чтобы он блокировал ожидание, снимите флаг WNOHANG. Однако обратите внимание, что он все еще может вернуться до изменения дочернего состояния, если вызов прерывается обработчиком сигнала. Если вас не волнует, успешно ли вышел ребенок, вы можете написать:

while (waitpid(PID, &chldstat, 0) == -1 && errno == EINTR)
    ;
...