2010-07-09 18 views
2

J'ai écrit ce code:C - fourchette - problème attendre

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

Programme ne faut pas attendre une itération complète et commence la prochaine itération!
regard sur les résultats:

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 *** 

Qu'en est-ce?
J'ai utilisé wait (NULL) mais ...

+0

Est-ce ce devoir? –

+0

non, je le fais pour quelqu'un – RYN

+0

Par ailleurs, '% lf' n'est pas le bon format pour le double. C'est simplement '% f'. Des fonctions comme 'printf' avec un nombre variable d'arguments sont sujettes à des promotions par défaut, ce qui signifie qu'il n'y a aucun moyen de passer un flottant sans qu'il soit promu en double. –

Répondre

7

wait() attend seulement qu'un seul processus fils se termine. Vous voulez attendre qu'ils soient tous sortis. Je pense que vous avez simplement besoin de l'appeler 3 fois de suite ...

+0

A travaillé! Merci beaucoup – RYN

1

Vous n'attendez pas correctement vos processus enfants créés. Vous devriez le faire comme ceci:

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

Il semble plutôt terrible, et vous devez repenser votre logique de programme pour le rendre plus lisible. N'oubliez pas de nettoyer correctement vos ressources des processus enfants avant de quitter (voir shmdt).

Une autre chose à considérer est d'utiliser shm_open et shm_unlink à la place.