【问题标题】:Prints before execl is not visible in outputexecl 之前的打印在输出中不可见
【发布时间】:2014-05-16 07:07:36
【问题描述】:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

int main(void)
{
    pid_t Checksum_pid = fork();

    if (Checksum_pid < 0)
        printf("Fork Failed\n");
    else if (Checksum_pid == 0)
    {
    printf("\nInside Child Process before execl");        
    //execl("/bin/sleep", "/bin/sleep", "2", NULL);
    execl("/bin/ls","ls",(char *)NULL) ;
        //exit(EXIT_FAILURE);
    printf("\nInside Child Process after execl\n");
    exit(EXIT_FAILURE);
    }
    else
    {
        int childStatus;        
    printf("\nInside Parent Process");
    sleep(5);
    pid_t returnValue = waitpid(Checksum_pid, &childStatus, WNOHANG);

        if (returnValue > 0)
        {
            if (WIFEXITED(childStatus))
                printf("\nChild Exit Code: %d\n", WEXITSTATUS(childStatus));
            else
                printf("\nChild Exit Status: 0x%.4X\n", childStatus);
        }
        else if (returnValue == 0)
            printf("\nChild process still running\n");
        else
        {
            if (errno == ECHILD)
                printf("\nError ECHILD!!\n");
            else if (errno == EINTR)
                printf("\nError EINTR!!\n");
            else
                printf("\nError EINVAL!!\n");
        }
    printf("\nParent: I am about to finish\n");
    }

    return 0;
}

输出:

kth4kor-2:~/bosch/Test1$ ./a.out  a.out  ___waitpid_test1  waitpid_test1~  waitpid_test1.c  waitpid_test1.c~  waitpid_test2.c  waitpid_test2.c~ 
Inside Parent Process Child Exit Code: 0
Parent: I am about to finish

现在,如果我将在父级中删除 sleep(5),则输出:

kth4kor-2:~/bosch/Test1$ ./a.out 
Inside Parent Process

Child process still running

Parent: I am about to finish

kth4kor@g3gdev-kth4kor-2:~/bosch/Test1$ a.out  ___waitpid_test1  waitpid_test1~  waitpid_test1.c  waitpid_test1.c~  waitpid_test2.c  waitpid_test2.c~

最后,我尝试使用 0 作为 waitpid 而不是 WNOHANG 的第三个参数,然后它给了我下面的输出以及任何孩子的打印:

kth4kor-2:~/bosch/Test1$ ./a.out 
a.out  ___waitpid_test1  waitpid_test1~  waitpid_test1.c  waitpid_test1.c~  waitpid_test2.c  waitpid_test2.c~
Inside Parent Process
Child Exit Code: 0
Parent: I am about to finish

有人可以帮助我了解执行 execl 之后和执行之前进程的行为吗?

【问题讨论】:

  • 除了@Joachim 提到的解决方案,您可以使用setbuf(stdout, NULL); 设置禁用缓冲或在stderr 上打印您的消息。
  • printf("\nInside Child Process before execl\n");工作正常...

标签: c linux exec printf waitpid


【解决方案1】:

请记住,通过printf(到stdout)的输出通常是行缓冲。这意味着输出缓冲区在换行符上被刷新。由于要打印的字符串后面没有换行符,因此不会刷新输出缓冲区。

要么在字符串的最后添加一个换行符,要么使用fflush 手动刷新缓冲区。

【讨论】:

  • @kapilddit 如果execl(和家人)成功,它将返回。它只会在失败时返回。所做的是将当前进程的图像(粗略的程序)替换为调用加载的图像。
  • @kapilddit sleep 函数只是让当前进程休眠一会儿,没有别的。唯一可以孤立进程的方法是父进程在子进程之前退出。
  • @kapilddit 我想我误解了你关于“孩子还在跑步的问题”。您无法控制特定流程何时运行,并且您无法事先知道流程需要多长时间。当您删除sleep 调用时,操作系统似乎在运行父进程之前或比子进程更快,因此它可能在子进程之前退出(子进程可能在之后退出您的waitpid 调用但在父进程退出之前)。当父进程sleep子进程有时间在睡眠结束前完成。
  • @kapilddit 可能,但您无法真正判断子级是否在父级中的最后一次printf 调用和main 函数中的return 之间退出。这不太可能,但它可能会发生。但这并不重要,因为如果孩子在waitpid 调用之前没有退出,那么无论进程退出的顺序如何,它都会成为孤儿。原因是如果父进程在等待所有子进程退出之前退出,子进程将成为孤立的。
  • @kapilddit 成功的wait(或waitpid等)调用导致子进程不会成为孤立的。
猜你喜欢
  • 2013-03-21
  • 1970-01-01
  • 1970-01-01
  • 2023-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多