C - fork - 等问题

时间:2010-07-09 18:54:23

标签: 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  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);
}  

程序不会等到一次迭代完成并开始下一次迭代! 看结果:

Iteration #1
    Child process 0 (Iteration 0) is done ***
    Child process 3 (Iteration 0) is done ***
    Child process 1 (Iteration 0) is done ***
Iteration #2
    Child process 2 (Iteration 0) is done ***
    Child process 0 (Iteration 1) is done ***
    Child process 1 (Iteration 1) is done ***
    Child process 3 (Iteration 1) is done ***
Iteration #3
    Child process 2 (Iteration 1) is done ***
    Child process 0 (Iteration 2) is done ***
    Child process 3 (Iteration 2) is done ***
Iteration #4
    Child process 1 (Iteration 2) is done ***
    Child process 2 (Iteration 2) is done ***
    Child process 1 (Iteration 3) is done ***
    Child process 3 (Iteration 3) is done ***
Iteration #5
    Child process 0 (Iteration 3) is done ***
    Child process 2 (Iteration 3) is done ***
    Child process 0 (Iteration 4) is done ***
    Child process 1 (Iteration 4) is done ***
    Child process 2 (Iteration 4) is done ***
    Child process 3 (Iteration 4) is done ***
Iteration #6
    Child process 1 (Iteration 5) is done ***
    Child process 0 (Iteration 5) is done ***
    Child process 2 (Iteration 5) is done ***
    Child process 3 (Iteration 5) is done ***
Iteration #7
    Child process 0 (Iteration 6) is done ***
    Child process 1 (Iteration 6) is done ***
    Child process 2 (Iteration 6) is done ***
    Child process 3 (Iteration 6) is done ***

这个怎么样?
我用了wait(NULL)但是......

2 个答案:

答案 0 :(得分:7)

wait()只会等到单个子进程退出。你想等到他们都退出了。我想你只需要连续三次打电话......

答案 1 :(得分:1)

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

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

它看起来很糟糕,你应该重新考虑你的程序逻辑,使它更具可读性。另外,请记住在退出之前从子进程中正确清理资源(请参阅shmdt)。

要考虑的另一件事是使用shm_openshm_unlink代替。