代码之家  ›  专栏  ›  技术社区  ›  Ariyan

C-分叉-等待问题

  •  2
  • Ariyan  · 技术社区  · 16 年前

    我写了这个代码:

    #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 回复  |  直到 16 年前
        1
  •  7
  •   R.. GitHub STOP HELPING ICE    16 年前

    wait()

        2
  •  1
  •   the_void    16 年前

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

    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_open 和 shm_unlink 相反。

    推荐文章