Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在子返回中使用带有execl的waitpid-1和ECHILD?_C_Linux_Fork_Waitpid_Os.execl - Fatal编程技术网

在子返回中使用带有execl的waitpid-1和ECHILD?

在子返回中使用带有execl的waitpid-1和ECHILD?,c,linux,fork,waitpid,os.execl,C,Linux,Fork,Waitpid,Os.execl,如果我使用的是execl is子进程可能需要时间才能完成,那么何时需要使用waitpid 当我在父级中使用waitpid时,它会给我运行的子级,因为waitpid的返回值为0。我试图在另一个函数中使用waitpid,在这个函数中,它返回带有ECHILD的me-1。如果我不确定孩子是否完成,我应该在什么时候使用waitpid //pid_t Checksum_pid = fork(); Checksum_pid = fork(); if (Checksum_pid == 0) { exe

如果我使用的是execl is子进程可能需要时间才能完成,那么何时需要使用waitpid

当我在父级中使用waitpid时,它会给我运行的子级,因为waitpid的返回值为0。我试图在另一个函数中使用waitpid,在这个函数中,它返回带有ECHILD的me-1。如果我不确定孩子是否完成,我应该在什么时候使用waitpid

//pid_t Checksum_pid = fork();
Checksum_pid = fork();

if (Checksum_pid == 0)
{
    execl(path, name, argument as needed, ,NULL);
    exit(EXIT_SUCCESS);     
}
else if (Checksum_pid > 0)
{ 
    pid_t returnValue = waitpid(Checksum_pid, &childStatus, WNOHANG);

    if ( returnValue > 0)
    {
        if (WIFEXITED(childStatus))
        {
            printf("Exit Code: _ WEXITSTATUS(childStatus)") ;               
        }
    }
    else if ( returnValue == 0)
    {
        //Send positive response with routine status running (0x03)
        printf("Child process still running") ; 
    }
    else
    {
        if ( errno == ECHILD )
        {
             printf(" Error ECHILD!!") ;
        } 
        else if ( errno == EINTR )
        {
            // other real errors handled here.
            printf(" Error EINTR!!") ;
        }
        else
        {
            printf("Error EINVAL!!") ;
        }       
    }
}
else
{   
    /* Fork failed. */
    printf("Fork Failed") ;
}

如果您使用
WNOHANG
等待,则除非您的孩子已经死亡,否则您将无法获得任何有用的状态,而且它甚至可能还没有开始运行(当家长执行
waitpid()
时,它可能仍在等待从磁盘加载可执行文件)

如果您想知道子进程已完成,请不要对第三个参数使用
WNOHANG
-使用
0
,除非您想知道未跟踪或继续的进程。这将等待
Checksum\u pid
标识的进程退出,或者系统通过某种神秘的方式(我从未见过这种情况发生)失去对它的跟踪


此代码生成退出代码0作为输出:

#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)
    {
        execl("/bin/sleep", "/bin/sleep", "2", NULL);
        exit(EXIT_FAILURE);
    }
    else
    {
        int childStatus;
        pid_t returnValue = waitpid(Checksum_pid, &childStatus, 0);

        if (returnValue > 0)
        {
            if (WIFEXITED(childStatus))
                printf("Exit Code: %d\n", WEXITSTATUS(childStatus));
            else
                printf("Exit Status: 0x%.4X\n", childStatus);
        }
        else if (returnValue == 0)
            printf("Child process still running\n");
        else
        {
            if (errno == ECHILD)
                printf(" Error ECHILD!!\n");
            else if (errno == EINTR)
                printf(" Error EINTR!!\n");
            else
                printf("Error EINVAL!!\n");
        }
    }

    return 0;
}
#包括
#包括
#包括
#包括
#包括
内部主(空)
{
pid_t校验和_pid=fork();
if(校验和pid<0)
printf(“Fork失败\n”);
else if(校验和=0)
{
execl(“/bin/sleep”、“/bin/sleep”、“2”、NULL);
退出(退出失败);
}
其他的
{
国际儿童地位;
pid_t returnValue=waitpid(校验和&childStatus,0);
如果(返回值>0)
{
如果(妻子退出(子女身份))
printf(“退出代码:%d\n”,WEXITSTATUS(childStatus));
其他的
printf(“退出状态:0x%.4X\n”,childStatus);
}
else if(returnValue==0)
printf(“子进程仍在运行\n”);
其他的
{
if(errno==ECHILD)
printf(“错误ECHILD!!\n”);
else if(errno==EINTR)
printf(“错误EINTR!!\n”);
其他的
printf(“错误EINVAL!!\n”);
}
}
返回0;
}
它与您的代码非常相似;我只是将
fork()
的检查移到了顶部。我仍然希望去掉
if
语句中的“茂密树”,但这并不重要。运行此代码时会发生什么情况?要获得
ECHILD
错误,您需要更改什么(您可以更改它以获得
ECHILD
错误)

当您成功地获得了基于此的代码来重现问题时,我们可以找出为什么会出现这种行为

在Mac OS X 10.9.2 Mavericks和GCC 4.8.2上进行了测试,在Ubuntu 13.10和GCC 4.8.1上也进行了测试(我需要添加
-D_XOPEN_SOURCE=700
以使其使用我严格的编译标志进行编译;Mac OS X不使用该标志进行管理),但我不希望在其他地方得到不同的结果。

int start(int Area)
int start(int Area)
{

        int childStatus;
        pid_t Checksum_pid = fork();

        if(Checksum_pid < 0)
        {   
            /* Fork failed. */
            printf(" Fork Failed") ;

        }   
        else if (Checksum_pid == 0)         
        {

            for (int i = 0; i<5; i++)

            {

                if ( g_area[i] == Area)
                {

                    execl(ScriptPath, ScriptName, NULL);

                }
            }

            exit(EXIT_FAILURE);

        }

        else        
        { 
            /* This is the parent process. */           
            pid_t returnValue = waitpid(Checksum_pid, &childStatus, 0);


            if ( returnValue > 0)
            {
                // Check if child ended normally 
                printf("WAITPID Successful") ;                  

                if (WIFEXITED(childStatus))
                {
            printf("Exit Code: _ WEXITSTATUS(childStatus)");
                }

            }

            else if ( returnValue == 0)
            {

                printf("Child process still running") ;

            }
            else
            {

                if ( errno == ECHILD )
                {
                     printf("Error ECHILD!!") ;
                } 
                else if ( errno == EINTR )
                {
                    printf("Error EINTR!!") ;
                }
                else
                {
                    printf(" Error EINVAL!!") ;
                }       
                retCode = FAILED;
            }        

        }            
}
{ 国际儿童地位; pid_t校验和_pid=fork(); if(校验和pid<0) { /*Fork失败了*/ printf(“Fork失败”); } else if(校验和=0) { 对于(int i=0;i 0) { //检查孩子是否正常结束 printf(“WAITPID Successful”); 如果(妻子退出(子女身份)) { printf(“退出代码:uwexitstatus(childStatus)”; } } else if(returnValue==0) { printf(“子进程仍在运行”); } 其他的 { if(errno==ECHILD) { printf(“错误ECHILD!!”); } else if(errno==EINTR) { printf(“错误EINTR!!”); } 其他的 { printf(“错误EINVAL!!”); } retCode=失败; } } }
如果忽略信号SIGCHLD(这是默认值),并且您跳过Jonathan提到的WNOHANG,waitpid将挂起,直到子项退出,然后使用代码ECHILD失败。我自己在一个场景中遇到过这种情况,父进程只需等待子进程完成,为SIGCHLD注册一个处理程序似乎有点过火。自然的后续问题是“在这种情况下,是否可以将ECHILD视为预期事件,还是我应该一直为SIGCHLD编写处理程序?”, 但我没有答案

从:

梯田

(对于waitpid()或waitid())由pid(waitpid())指定的进程 或idtype和id(waitid())不存在或不是的子级 呼叫过程。(这可能发生在自己的孩子身上,如果 for SIGCHLD设置为SIG_IGN。另请参阅Linux说明部分关于 线程。)

再往下

POSIX.1-2001规定,如果SIGCHLD的处置设置为 为SIGCHLD设置SIG_IGN或SAU NOCLDWAIT标志(请参阅 sigaction(2)),则终止的子对象不会变成僵尸,并且 对wait()或waitpid()的调用将被阻止,直到所有子项 终止,然后在errno设置为ECHILD时失败。(原文) POSIX标准保留了将SIGCHLD设置为SIG_IGN的行为 未指定。请注意,即使SIGCHLD的默认配置 是“忽略”,显式地将处置设置为SIG_IGN会导致 对僵尸进程子进程的不同处理。)Linux 2.6符合 本规范。但是,Linux2.4(及更早版本)没有:如果 在忽略SIGCHLD时进行wait()或waitpid()调用 调用的行为就像SIGCHLD没有被忽略一样,也就是说, 调用将一直阻塞,直到下一个子项终止,然后返回 过程