C-叉-等待问题

C-叉-等待问题,c,fork,wait,C,Fork,Wait,我写了这段代码: #include <stdio.h> #include <stdlib.h> #include <time.h> #include <sys/types.h> #include <sys/shm.h> #define N 512 void chunk0(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it); void chun

我写了这段代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <sys/shm.h>

#define   N  512

void  chunk0(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it);
void  chunk1(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it);
void  chunk2(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it);
void  chunk3(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it);
double get_time(void);

void  main(void)
{
    int i,j,k,iterations=0;
    int plc=N/4;
    unsigned int *a=(unsigned int *)malloc(N*N*(sizeof(unsigned int)));
    unsigned int *b=(unsigned int *)malloc(N*N*(sizeof(unsigned int)));
    unsigned int shmsz=N*N*(sizeof(unsigned int));
    pid_t  pid;

    srand ( time(NULL) );
    double start=get_time();

    int shmid;
    if ((shmid = shmget(IPC_PRIVATE, shmsz, IPC_CREAT | 0666)) < 0) {
        perror("shmget");
        exit(1);
    }
    //Now we attach the segment to our data space.
    char *shm;
    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
        perror("shmat");
        exit(1);
    }   
    unsigned int *s = (unsigned int *) shm;

    for(iterations=0;iterations<1000;iterations++){
        printf("Iteration #%d\n",iterations+1);
        for(i=0;i<N;i++){
            for(j=0;j<N;j++){
                *(a+(i*N+j))=(rand()%1001);
                *(b+(i*N+j))=(rand()%1001);;
                *(s+(i*N+j))=0;
            }
        }

        pid = fork();
        if (pid == 0) {
             chunk0(s,a,b,plc,iterations);
             break;
        }else {
            pid = fork();
            if (pid == 0){ 
                 chunk1(s,a,b,plc,iterations);
                 break;
            }else {
                pid = fork();
                if (pid == 0){ 
                     chunk2(s,a,b,plc,iterations);
                     break;
                }else {
                    chunk3(s,a,b,plc,iterations);
                    wait(NULL);
                }
            }
        }
        wait(NULL);
    }

    double end=get_time();
    double diff=end-start;
    printf("\n Time for run this code is: %lf seconds \n",diff);

}

void  chunk0(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it)
{
    int i,j,k;

    for(i=0;i<MID;i++){
        for(j=0;j<N;j++){
            for(k=0;k<N;k++){
                *(s+(i*N+j))=*(s+(i*N+j))+(*(a+(i*N+k)))*(*(b+(k*N+j)));
            }   
        }
    }
    printf("\tChild process 0 (Iteration %d) is done ***\n",it);
    exit(0);
}
void  chunk1(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it)
{
    int i,j,k;

    for(i=MID;i<MID*2;i++){
        for(j=0;j<N;j++){
            for(k=0;k<N;k++){
                *(s+(i*N+j))=*(s+(i*N+j))+(*(a+(i*N+k)))*(*(b+(k*N+j)));
            }
        }
    }
     printf("\tChild process 1 (Iteration %d) is done ***\n",it);
     exit(0);
}
void  chunk2(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it)
{
    int i,j,k;

    for(i=MID*2;i<MID*3;i++){
        for(j=0;j<N;j++){
            for(k=0;k<N;k++){
                *(s+(i*N+j))=*(s+(i*N+j))+(*(a+(i*N+k)))*(*(b+(k*N+j)));
            }
        }
    }

     printf("\tChild process 2 (Iteration %d) is done ***\n",it);
     exit(0);
}
void  chunk3(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it)
{
     int i,j,k;

    for(i=MID*3;i<N;i++){
        for(j=0;j<N;j++){
            for(k=0;k<N;k++){
                *(s+(i*N+j))=*(s+(i*N+j))+(*(a+(i*N+k)))*(*(b+(k*N+j)));
            }
        }
    }

     printf("\tChild process 3 (Iteration %d) is done ***\n",it);
//     exit(0);
}

double get_time(void){
    struct timeval stime;
    gettimeofday (&stime, (struct timezone*)0);
    return (stime.tv_sec+((double)stime.tv_usec)/1000000);
}  
这个怎么样?

我使用了wait(NULL),但是…

wait()
将只等待一个子进程退出。你想等到他们全部离开。我认为您只需要连续调用它3次…

您没有正确地等待创建的子进程。你应该这样做:

pid = fork();
if (pid == 0) {
    chunk0(s,a,b,plc,iterations);
    break;
}else {
    pid = fork();
    if (pid == 0){ 
        chunk1(s,a,b,plc,iterations);
        break;
    }else {
        pid = fork();
        if (pid == 0){ 
            chunk2(s,a,b,plc,iterations);
            break;
        }else {
            chunk3(s,a,b,plc,iterations);
            wait(NULL);
        }
        wait(NULL);
    }
    wait(NULL);
}
它看起来相当糟糕,您应该重新考虑您的程序逻辑,使其更具可读性。此外,请记住在退出之前正确清理子进程中的资源(请参阅)


顺便说一下,

顺便说一下,<代码> %LF不是双倍的正确格式。它只是
%f
。具有可变参数数的函数,如
printf
,会受到默认提升的影响,这意味着如果不将普通浮点提升为双精度,则无法传递普通浮点。
pid = fork();
if (pid == 0) {
    chunk0(s,a,b,plc,iterations);
    break;
}else {
    pid = fork();
    if (pid == 0){ 
        chunk1(s,a,b,plc,iterations);
        break;
    }else {
        pid = fork();
        if (pid == 0){ 
            chunk2(s,a,b,plc,iterations);
            break;
        }else {
            chunk3(s,a,b,plc,iterations);
            wait(NULL);
        }
        wait(NULL);
    }
    wait(NULL);
}