1

代码不起作用,它进入循环。我认为错误出在 gestore 方法中,它是 SIGCHLD 信号的处理程序。这是我第一次使用处理程序来捕获 SIGCHLD 信号。这个程序继续从 0 到 argv[1] 随便提取,直到一个数字出现 argv[1] 次。如果不清楚,您可以测试我放在问题末尾的旧程序。你能帮我找出错误吗?

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>

int a;
void gestore(int segnale);
int main(int argc, char * argv[]){
    int n = atoi(argv[1]), i, pid;
    int * vec;
    vec = malloc((n+1)*sizeof(*vec));
    memset (vec, 0, sizeof(*vec));
    char * newargv[] = {argv[0], argv[1] , NULL};
    for(i = 0; i < n; i++){
        pid = fork();
        if (pid == 0)
            execve("./throw-dice", newargv, NULL);
        signal(SIGCHLD, gestore);
        vec[WEXITSTATUS(a)]++;
    }
    while(vec[i] != n){
        for(i = 1; i < n+1 && vec[i] != n; i++){
            if(vec[i] != 0){
                pid = fork();
                if (pid == 0)
                    execve("./throw-dice", newargv, NULL);
                signal(SIGCHLD, gestore);
                vec[WEXITSTATUS(a)]++;
            }
        }
    }
    printf("The value %d is appeared %d times!\n", i, vec[i]);
    while (wait(&a) != -1);
    free(vec);
}

void gestore(int segnale){
    signal(segnale, SIG_IGN);
    waitpid(WAIT_ANY, &a, WNOHANG);
    signal(segnale, gestore);
}

我的目标是修改我的旧程序(有效),改变我捕获孩子退出状态的方式。从与“等待”同步到与处理 SIGCHLD 信号的 gestore 方法异步。这是我的旧程序:

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

int main(int argc, char * argv[]){
    int n = atoi(argv[1]), a, i, pid;
    int * vec;
    vec = malloc((n+1)*sizeof(*vec));
    memset (vec, 0, sizeof(*vec));
    char * newargv[] = {argv[0], argv[1] , NULL};
    for(i = 0; i < n; i++){
        pid = fork();
        if (pid == 0)
            execve("./throw-dice", newargv, NULL);
        wait(&a);
        vec[WEXITSTATUS(a)]++;
    }
    while(vec[i] != n){
        for(i = 1; i < n+1 && vec[i] != n; i++){
            if(vec[i] != 0){
                pid = fork();
                if (pid == 0)
                    execve("./throw-dice", newargv, NULL);
                wait(&a);
                vec[WEXITSTATUS(a)]++;
            }
        }
    }
    printf("The value %d is appeared %d times\n", i, vec[i]);
    while (wait(&a) != -1);
    free(vec);
}

//掷骰子.c

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char * argv[]) {
    int n, val;
    // Must have an argument
    if (argc < 2) {
        exit(-1);
    }
    // the 1st argument must be a positive number
    if ((n = atoi(argv[1])) <= 0) {
        exit(-1);
    }
    //  sleep(1); // sleep a bit
    srand(getpid()); // initialize the random seed with PID
    val = rand() % n + 1;
    printf("(PID=%d): got number %d\n", getpid(), val);
    exit(val);
}
4

0 回答 0