Multiplication de matrices et fork() en C
Hors ligneFred51 Le 28/03/2006 à 21:32 Profil de Fred51 Configuration de Fred51

Bonsoir tout le monde.

J'ai un petit problème en C. Je dois créer un programme qui effectue la multiplication de deux matrices d'entiers, en utilisant plusieurs processus.
Voici le code source :

Dans le fichier Matrice.h :

typedef struct Matrice{
  int nbLignes, nbColonnes;
  int **matrice;
}Matrice;

**********************

Dans le fichier Matrice.c :

Matrice* Matrice_creation(int nbL, int nbC){

  int i;

  Matrice* tmp=(Matrice*)malloc(sizeof(Matrice));
  tmp->nbLignes=nbL;
  tmp->nbColonnes=nbC;
  tmp->matrice=(int**)malloc(sizeof(int*)*nbL);
  for(i=0;i<nbL;i++){
      tmp->matrice[i]=(int*)malloc(sizeof(int)*nbC);
  }
  return tmp;


}

void calcul_ligne(Matrice* M1, Matrice* M2, Matrice* result, int i){
  int x,y;
  for(x=0;x<M2->nbLignes;x++){
    for(y=0;y<M1->nbColonnes;y++){
      result->matrice[i][y]+=M1->matrice[i][y]*M2->matrice[x][i];
    }
  }
}


*************************

Dans le fichier main.c :

(Je passe sur les fonctions de remplissage des deux matrices, qui fonctionnent bien)

  int nbC1; //nombre de colonnes de la matrice 1
  int nbL1; //nombre de lignes de la matrice 1
  int nbC2;
  int nbL2;
  int i, j;
  int diag;

Matrice *M1=Matrice_creation(nbL1,nbC1);
Matrice *M2=Matrice_creation(nbL1,nbC1);
Matrice *M3=Matrice_creation(nbL1,nbC1);

/* Je crée autant de processus que de lignes dans
       la matrice résultat (M3). Chaque processus calcule
       une ligne de la matrice   */

    for(i=0; i<nbL1; i++){
      diag=fork();
      if(diag<0)
     perror("fork");
      else
     if(diag==0){
       calcul_ligne(M1,M2,M3,i);
       exit(0);
     }
    }

/* J'attend que tous les fils terminent leurs calculs */
  
    for(i=0;i<nbL1;i++){
      diag=wait(0);
      if(diag<0)
     perror("wait");
    }


*********************************************************

Bon alors tout ceci se compile très bien, le problème c'est que la matrice résultat n'est constituée que de zéros au final. C'est comme si les fils faisaient bien leur travail, mais que cela n'avait aucune incidence sur la matrice M3.
Si quelqu'un voit de quoi cela peut provenir...

Merci d'avance ^^.
Hors ligneAsquel Le 21/04/2006 à 14:31 Profil de Asquel Configuration de Asquel

tu ne passes pas l'id du père au processus fils si je ne m'abuse donc ils ne connaissent pas leur père
Hors ligneAralicia Le 26/06/2007 à 16:45 Profil de Aralicia Configuration de Aralicia

Bonjour.

D'après ce que j'ai pus voir, je pense que tu code sous Unix/Linux/Alpha/Solaris (rayer les mentions inutiles) et je vais donc répondre pour ces systèmes.

Ton programme ne fonctionne pas pour la raison suivante : lors d'un fork, le père ne conserve pas les modification effecutées par son fils. Cela peux ce verifier en imprimant le resultat des calculs à la fin de la fonction calcul_line. ils sont exacts, mais leur résultat n'est pas retourné au processus père (puisque la matrice finale est indentique à l'origine).
Pour le pourquoi du comment, je n'en sais rien et je ne peut donc pas t'aider à corriger ton programme. Pour me faire pardonner, je vais mettre quelques autres idées pour le coder.
As tu pensé à utiliser la valeur de retour d'un processus en tant que retour de calcul ?
En clair, tu crée un processus pour chaque case du tableau représentant la matrice finale. celui-ci fait le calcul pour la case qui lui est dédiée est la renvoie au père par le bais d'un exit(valeur).
La récuperation ce fait grace à l'appel à wait4(), qui retourne un type opaque. l'utilisation de WEXITSTATUS() permet de récuperer la valeur de l'exit.
D'autres moyens sont possibles en passant le pid du programme père aux fils qui lui enveront alors l'information d'une manière ou d'un autre (par exemple en utilisant des socket (O_o') ou encore en décomposant l'int en binaire et le retournant au père par le bais de SIGUSR1 et SUGUSR2, mais aussi...).

Ceci dis, je trouve que l'idée de forker un programme pour une tâche aussi bête qu'une multiplication matricielle, qui somme toute tiens dans un fonction d'une dizaine de lignes particulièrement débile. Je me doute que ce projet avais pour but de vous apprendre à faire des fork(), mais il y avait mieux à faire, quand même. Recoder la fonction system() par exemple.

Bonne journée
Hors ligneEndiku Le 27/06/2007 à 00:26 Profil de Endiku Configuration de Endiku

Bonsoir,

les memoires des processus sont separees. Les processus fils heritent d'une copie de la memoire du pere. Mais les calculs faits par les processus fils ne sont donc pas repercutes sur la memoire du processus pere.

Il faudrait ici, je crois, utiliser une memoire partagee pour la matrice resultat M3 (memoire partagee=IPC, Inter Process Communication).

Endiku.
Vous avez résolu votre problème avec VIC ? Faites-le savoir sur les réseaux sociaux !
Vulgarisation-informatique.com
Cours en informatique & tutoriels