C - 线程和进程 - 防止僵尸

时间:2015-12-25 22:36:23

标签: c multithreading process fork

我正在实现一个接收解析到数组命令行的函数("./waiter 20 &"将被解析,函数将接收数组 例如{"./waiter","20","&"}。 如果最后一个参数是&,则该进程应在​​后台运行。 为了防止僵尸,我需要使用一个等待子进程的新线程。 附加的代码是我的工作程序,我所有努力添加一个等待子进程的新线程都失败了。 有人可以指导我吗? 附上代码,以及我不成功尝试的一些剩余部分。 (函数为process_arglist

更新:经过大量尝试使用此处建议后,它仍然失败,我不知道为什么。附上更新的代码。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>

void func(void* ptr) {
    pid_t* mypid = (pid_t*)ptr;
    waitpid(*mypid);
    pthread_detach(pthread_self());
}

int process_arglist(int count, char** arglist){
    int isBackground = 0;
    pid_t  pid;
    int    status;
    char** parsedList;
    if (strcmp(arglist[count-1],"&") == 0) {
        printf("###we are in the & situation\n");
        parsedList = (char**)malloc((count-1)*sizeof(char*));
        if (parsedList == NULL) {
            printf( "Error: malloc failed - %s\n", strerror(errno));
        }
        int i;
        for (i=0;i<count-1;i++){
            parsedList[i] = arglist[i];
        }
        /*printf("parsed list:\n");
        for (i=0;i<count-1;i++) {
            printf(" %d: %s\n", i,parsedList[i]);
        }*/
        if ((pid = fork()) < 0) {     /* fork a child process           */
            printf( "Error: fork failed");
            exit(0);
        } else if (pid == 0) {          /* for the child process:         */
            if (execvp(*parsedList,parsedList) < 0) {     /* execute the command  */
                printf( "Error: execvp failed - %s\n", strerror(errno));
                exit(0);
            }
        } else {
            pthread_t thread;
            pthread_create(&thread, NULL, (void*) &func, (void*) &pid);
        }
    } else {
        if ((pid = fork()) < 0) {     /* fork a child process           */
            printf( "Error: forking child process failed - %s\n", strerror(errno));
            exit(0);
        }
        else if (pid == 0) {          /* for the child process:         */
            if (execvp(*arglist,arglist) < 0) {     /* execute the command  */
                printf( "Error: execvp failed - %s\n", strerror(errno));
                exit(0);
            }
        }
        else {                                  /* for the parent:      */
            while (waitpid(&status) != pid);       /* wait for completion  */
        }
    }
}

1 个答案:

答案 0 :(得分:1)

首先,从致电wait切换到致电waitpid。否则,如果您有多个线程在等待,它们会窃取彼此的通知。

其次,将对waitpid的调用分解为自己的函数,该函数使PID等待作为参数。通过void *强制转换,因为这是用于线程参数的内容。

第三,将对函数的调用更改为对pthread_create的调用,将PID转换为等待void *传递给新创建的线程。

最后,让线程自行分离,因为没有任何东西等待线程终止。