我正在使用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?
答案 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");
}