gpt4 book ai didi

c - wait(status)、WEXITSTATUS(status) 始终返回 0

转载 作者:行者123 更新时间:2023-11-30 18:29:47 33 4
gpt4 key购买 nike

我正在开发一个使用 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(status) 总是返回 0 是否有原因?

最佳答案

这里:

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

关于c - wait(status)、WEXITSTATUS(status) 始终返回 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35471521/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com