2010-11-20 4 views
0

HI,Problèmes lors de l'exécution du programme à l'aide de la mémoire partagée; seg faute parfois; shmmax et shmall ont quelque chose à voir avec ça?

J'ai un programme dans lequel un maître traite spawns N travailleurs qui vont inverser, chacun, chaque ligne d'une image, en me donnant une image inversée à la fin. Le programme utilise la mémoire partagée et les sémaphores posix, sems sans nom, plus spefically et j'utilise shmctl avec IPC_RMID et sem_close et sem_destroy dans la fonction terminate(). Cependant, lorsque je lance le programme plusieurs fois, il me donne parfois un défaut de segmentation et est dans le premier shmget. J'ai déjà modifié ma valeur shmmax dans le noyau, mais je ne peux pas faire la même chose avec la valeur shmall, je ne sais pas pourquoi.

Quelqu'un peut-il m'aider s'il vous plaît? Pourquoi cela arrive et pourquoi n'est-ce pas tout le temps? Le code semble bien, me donne ce que je veux, efficace et ainsi de suite ... mais parfois je dois redémarrer Ubuntu pour pouvoir le lancer à nouveau, même si je pense que je vais libérer les ressources.

S'il vous plaît éclairer moi!

EDIT:

Voici les 3 fichiers nécessaires pour exécuter le code + le makefile:
http://pastebin.com/JqTkEkPv
http://pastebin.com/v7fQXyjs
http://pastebin.com/NbYFAGYq

http://pastebin.com/mbPg1QJm

Vous devez exécuter comme ça./inverser someimage.ppm outimage.ppm (tester avec un petit pour l'instant s'il vous plaît)

Voici quelques valeurs qui peuvent être importantes:

$ipcs -lm 
------ Shared Memory Limits -------- 
max number of segments = 4096 
max seg size (kbytes) = 262144 
max total shared memory (kbytes) = 8388608 
min seg size (bytes) = 1 

$ipcs -ls 

------ Semaphore Limits -------- 
max number of arrays = 128 
max semaphores per array = 250 
max semaphores system wide = 32000 
max ops per semop call = 32 
semaphore max value = 32767 

EDIT: la faute de SEG a été résolu! J'allouais un tableau ** dans la mémoire partagée et c'était un peu bizarre. Donc, j'ai alloué un segment pour un tableau * seulement et voilà. Si vous voulez, vérifiez le nouveau code et commentez.

+3

Ça va être difficile sans accès au code. – Lagerbaer

+0

Si vous pouvez réduire la zone de code à l'origine du défaut de segmentation, collez les lignes incriminées ici. – vpit3833

+0

J'ai modifié le post pour que vous puissiez voir les liens avec tout le code source – neverMind

Répondre

1

Maintenant que vous avez posté votre code, nous pouvons en dire un peu plus.

Sans avoir tout lu en détail, je pense que la phase de nettoyage de votre main semble suspectée. En fait, il me semble que tous vos processus de travail vont également effectuer cette phase de nettoyage. Après l'embranchement, vous devriez distinguer plus clairement ce que fait main et ce que font les travailleurs. Alternatives:

  • Votre processus principal pourrait tout wait sur les pid s des travailleurs et alors seulement le reste du traitement et le nettoyage.
  • Tous les processus de travail peuvent retourner dans main après l'appel à worker.
  • Appelez exit à la fin de la fonction travailleur.

Modifier après votre mise à jour de code:

Je pense encore une meilleure solution serait de faire un wait classique pour tous les processus.

Maintenant, regardons dans votre processus de travail. En fait, ceux-ci ne se terminent jamais, il n'y a pas d'instruction break dans la boucle while (1). Je pense que ce qui se passe est qu'une fois qu'il n'y a pas plus de travail à faire

  • le travailleur est coincé dans sem_wait(sem_remaining_lines)
  • votre processus principal est notifié de la fin
  • détruit la sem_remaining_lines
  • le travailleur revient de sem_wait et continue
  • puisque mutex3 est également déjà détruit (Ou peut-être même unmapped) l'attente sur elle retourne immédiatement
  • maintenant il tente d'accéder aux données et en fonction de la distance du processus main a sur la destruction des données est mise en correspondance ou non et le travailleur accidents (ou non)

Comme vous pouvez le voir, vous avez beaucoup de problèmes là-dedans. Ce que je ferais pour nettoyer ce gâchis est

  • waitpid avant de détruire les données partagées
  • sem_trywait au lieu de 1 à while (1). Mais peut-être n'ai-je pas complètement compris votre flux de contrôle. Dans tous les cas, donnez-leur une condition de résiliation.
  • capturer tous les retours des fonctions système , en particulier la famille sem_t . Ceux-ci peuvent être interrompus par IO, donc vous définitivement doit vérifier pour EINTR sur ceux-ci.
+0

Ok, je vais essayer de faire ces changements et ensuite je vais poster.Merci – neverMind

+0

Vous pouvez voir mon premier nouveau lien dans mon message, s'il vous plaît? J'ai fait plus ou moins les changements que je me suis dit mais sans succès ... J'ai encore des problèmes avec shmget après 5-6 runs ... :( – neverMind

+0

J'ai changé un peu, au lieu d'allouer sh_mm à un tableau ** a fait un simple pointeur, parce que shmat renvoie (void) *. Donc, la faute de seg a été résolue Maintenant, j'ai fait quelques changements basés sur ce que vous m'avez dit, pourriez-vous vérifier s'il y a des incohérences? – neverMind

3

Si tous vos sem_t sémaphores sont sans nom POSIX vous ne devez utiliser sem_init et sem_destroy sur eux et jamais sem_close.

Questions connexes