1

完了するまでに時間がかかる可能性がある子プロセスでwaitpid使用している場合、いつ使用する必要がありますか?execl

親で使用するwaitpidと、からの戻り値waitpidが0であるため、子が実行されていることがわかります。ただし、waitpidしばらくして別の関数で呼び出すと、 errnoset toで-1が返されますECHILDwaitpid子供が完了したかどうかわからない場合は、いつ使用すればよいですか?

//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") ;
}
4

3 に答える 3

2

で待機するとWNOHANG、子がすでに死亡していない限り、有用なステータスは取得されません。また、まだ開始されていない可能性もあります (親が を実行したときに、実行可能ファイルがディスクからロードされるのをまだ待機している可能性がありますwaitpid()) 。 .

子が終了したことを知りたい場合は、使用しないでくださいWNOHANG0追跡されていない、または継続しているプロセスについて知りたい場合を除き、3 番目の引数に使用してください。これは、によって識別されたプロセスが終了するまで待機するChecksum_pidか、システムが不思議な手段 (私が見たことがない) によってそのプロセスを追跡できなくなるまで待機します。


このコードはExit Code: 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;
}

それはあなたのコードに非常に似ています。fork()失敗のチェックを一番上に移動しただけです。ステートメントの「ふさふさした木」を取り除くことを私はまだ望んでifいますが、それは重要ではありません。このコードを実行するとどうなりますか? エラーを取得するには何を変更する必要がありますかECHILD(エラーが発生するように変更できますECHILDか)?

これに基づいて問題を再現するコードを取得できた場合、その動作が発生する理由を突き止めることができます。

GCC 4.8.2 を搭載した Mac OS X 10.9.2 Mavericks と、GCC 4.8.1 を搭載した Ubuntu 13.10 でテストしました (-D_XOPEN_SOURCE=700厳しいコンパイル フラグでコンパイルするには、追加する必要がありました。Mac OS X はそれなしで管理されていました)。他の場所で異なる結果が得られるとは思わないでください。

于 2014-03-27T14:05:42.320 に答える
0
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;
            }        

        }            
}
于 2014-03-28T13:24:46.300 に答える