等待(状态),WEXITSTATUS(状态)始终返回0

时间:2016-02-18 02:11:34

标签: c unix

我正在使用fork()exec()wait()的c程序。 第一个过程有这个代码:

int main(int argc, const char * argv[]) {
// insert code here...

int pid = fork();

if(pid == 0){
    //we are the child process.
    execlp("/Users/matthewdunn/Library/Developer/Xcode/DerivedData/PA2-hekivoaqvsegnggdvcfguasystig/Build/Products/Debug/Checker", "Checker", "1", "5", (char*) NULL);
}else{
    //we are the parent process.
    printf("Coordinator: forked process with ID ");
    printf("%d\n", pid);

    printf("Coordinator: waiting for process [");
    printf("%d", pid);
    printf("]\n");

    int status;
    waitpid(pid, &status, 0);
    int returned = WEXITSTATUS(status);

    printf("Coordinator: child process ");
    printf("%d", pid);
    printf(" returned ");
    printf("%d", returned);
    printf(".\n");
}



  return 0;
}

第二个过程有代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

void printProcessInfo(){
    printf("Checker process [");
    printf("%d", getpid());
    printf("]:  ");
}

int main(int argc, const char * argv[]) {
    // insert code here...

    printProcessInfo();
    printf("Starting.\n");

    int arg1;
    int arg2;

    arg1 = atoi(argv[1]);
    arg2 = atoi(argv[2]);

    if((arg2 % arg1) > 0){
        printProcessInfo();
        printf("%d", arg2);
        printf(" *IS NOT* divisible by ");
        printf("%d\n", arg1);

        printProcessInfo();
        printf("Returning 0.\n");
        return 0;
    }
    else{
        printProcessInfo();
        printf("%d", arg2);
        printf(" *IS* divisible by ");
        printf("%d\n", arg1);

        printProcessInfo();
        printf("Returning 1.\n");
        return 1;
    }

}

由于我无法弄清楚的原因,即使我得到下降输出,父函数也总是读取返回值0:

Coordinator: forked process with ID 2865 
Coordinator: waiting for process [2865] 
Checker process [2865]:  Starting. 
Checker process [2865]:  5 *IS* divisible by 1 
Checker process [2865]:  Returning 1.
Coordinator: child process 2865 returned 0. 
Program ended with exit code: 0

第二个过程显然返回1,但我仍然得到0状态。我不知道是什么原因引起的。我正在使用Xcode编写此代码。有没有理由为什么WEXITSTATUS(状态)总是返回0?

1 个答案:

答案 0 :(得分:2)

下面:

int* status;
waitpid(pid, status, 0);

你的指针status永远不会被设置为实际指向任何东西。您需要一个实际的int来存储值:

int status;
waitpid(pid, &status, 0);

如果您对退出状态特别感兴趣,还应该检查以确保它确实正常退出。可以说,与所有系统调用一样,您应该在尝试使用该值执行任何操作之前检查waitpid()的错误返回。

共:

int status;
if ( waitpid(pid, &status, 0) != -1 ) {
    if ( WIFEXITED(status) ) {
        int returned = WEXITSTATUS(status);
        printf("Exited normally with status %d\n", returned);
    }
    else if ( WIFSIGNALED(status) ) {
        int signum = WTERMSIG(status);
        printf("Exited due to receiving signal %d\n", signum);
    }
    else if ( WIFSTOPPED(status) ) {
        int signum = WSTOPSIG(status);
        printf("Stopped due to receiving signal %d\n", signum);
    }
    else {
        printf("Something strange just happened.\n");
    }
}
else {
    perror("waitpid() failed");
    exit(EXIT_FAILURE);
}

这是一个有效的例子:

parent.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main(void)
{
    int pid = fork();

    if ( pid == -1 ) {
        perror("fork() failed");
        exit(EXIT_FAILURE);
    }
    else if ( pid == 0 ) {
        execlp("./child", "child", "1", "5", (char *)NULL);
        perror("execlp() failed");
        exit(EXIT_FAILURE);
    } else {
        printf("Coordinator: forked and waiting for process %d\n", pid);

        int status;
        if ( waitpid(pid, &status, 0) != -1 ) {
            if ( WIFEXITED(status) ) {
                int returned = WEXITSTATUS(status);
                printf("Exited normally with status %d\n", returned);
            }
            else if ( WIFSIGNALED(status) ) {
                int signum = WTERMSIG(status);
                printf("Exited due to receiving signal %d\n", signum);
            }
            else if ( WIFSTOPPED(status) ) {
                int signum = WSTOPSIG(status);
                printf("Stopped due to receiving signal %d\n", signum);
            }
            else {
                printf("Something strange just happened.\n");
            }
        }
        else {
            perror("waitpid() failed");
            exit(EXIT_FAILURE);
        }
    }

    return 0;
}

child.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

void printProcessInfo()
{
    printf("Checker process [%d]: ", getpid());
}

int main(int argc, char * argv[])
{
    printProcessInfo();
    printf("Starting.\n");

    int arg1, arg2;

    arg1 = atoi(argv[1]);
    arg2 = atoi(argv[2]);

    if ( (arg1 != 0) && (arg2 % arg1) > 0 ){
        printProcessInfo();
        printf("%d *IS NOT* divisible by %d\n", arg2, arg1);
        printProcessInfo();
        printf("Returning 0.\n");
        return 0;
    }
    else {
        printProcessInfo();
        printf("%d *IS* divisible by %d\n", arg2, arg1);
        printProcessInfo();
        printf("Returning 1.\n");
        return 1;
    }

    return 0;
}

带输出:

paul@horus:~/src/sandbox/ft$ ./parent
Coordinator: forked and waiting for process 40330
Checker process [40330]: Starting.
Checker process [40330]: 5 *IS* divisible by 1
Checker process [40330]: Returning 1.
Exited normally with status 1
paul@horus:~/src/sandbox/ft$ 

编辑:如果您在Xcode中构建此功能,那么您的waitpid()呼叫会被信号中断(最有可能是SIGCHLD)。在这种情况下,您只需要重新启动它,如下所示:

int status;
while ( waitpid(pid, &status, 0) == -1 ) {
    if (errno == EINTR) {
        printf("Parent interrrupted - restarting...\n");                   
        continue;
    }
    else {
        perror("waitpid() failed");
        exit(EXIT_FAILURE);
    }
}

if ( WIFEXITED(status) ) {
    int returned = WEXITSTATUS(status);
    printf("Exited normally with status %d\n", returned);
}
else if ( WIFSIGNALED(status) ) {
    int signum = WTERMSIG(status);
    printf("Exited due to receiving signal %d\n", signum);
}
else if ( WIFSTOPPED(status) ) {
    int signum = WSTOPSIG(status);
    printf("Stopped due to receiving signal %d\n", signum);
}
else {
    printf("Something strange just happened.\n");
}
相关问题