Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1013 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C] Core dumped avec pthread

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] Core dumped avec pthread

n°2441383
Shadoko
Anciennement Pharmaticien
Posté le 25-02-2023 à 15:39:25  profilanswer
 

Salut à tous :hello:
 
J'essaie de comprendre ma connerie que je n'arrive pas à identifier :pt1cable:
Je 'reprends' le C (niveau découverte) mais j'y rajoute le Multithreading, si certaines convention de forme ne sont pas respectées et que ça vous pique les yeux n'hésitez pas à m'engueuler :D
Au lancement du prog après un temps très court, j'ai quelque fois un core dump dans les 2-3 sec.
Si aucun problème déclaré vers le lancement, alors le programme se déroule jusqu'à la fin (testé avec de grandes limites).
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <unistd.h>
  5. #include <pthread.h>
  6. #include <string.h>
  7. typedef struct int_protege{
  8.     pthread_mutex_t intex;
  9.     int entier;
  10. }int_p;
  11. int_p incremented = {PTHREAD_MUTEX_INITIALIZER,0};
  12. void* routine_adding(){
  13.     int statut, compte;
  14.     while(incremented.entier < 10000){ //limite
  15.         pthread_mutex_unlock(&incremented.intex);
  16.         statut = pthread_mutex_trylock(&incremented.intex);
  17.         if (statut == 0){
  18.             incremented.entier += compte;
  19.             printf("%ld a augmenté de %d : %d\n", pthread_self(),compte,incremented.entier);
  20.             fflush(stdout);
  21.             compte = 0;
  22.             pthread_mutex_unlock(&incremented.intex);
  23.         }
  24.         compte++;
  25.         pthread_mutex_lock(&incremented.intex);
  26.     }
  27.     pthread_mutex_unlock(&incremented.intex);
  28. }
  29. int main(int argc, char** argv){
  30.     pthread_t thread1, thread2;
  31.     pthread_create(&thread1,NULL,&routine_adding,NULL);
  32.     pthread_create(&thread2,NULL,&routine_adding,NULL);
  33.     pthread_join(thread1,NULL);
  34.     pthread_join(thread2,NULL);
  35.     return EXIT_SUCCESS;
  36. }


 
Je suis sur VM linux mint xfce, ce pourrait-il que ça soit en lien avec mon PB ?
Merci pour la lecture !
 
EDIT du lendemain (Merci kajoux !) :
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <unistd.h>
  5. #include <pthread.h>
  6. #include <string.h>
  7. typedef struct int_protege{
  8.     pthread_mutex_t intex;
  9.     int entier;
  10. }int_p;
  11. int_p incremented = {PTHREAD_MUTEX_INITIALIZER,0};
  12. void* routine_adding(){
  13.     int statut, compte;
  14.     pthread_mutex_lock(&incremented.intex);
  15.     while(incremented.entier < 10000){ //limite
  16.         pthread_mutex_unlock(&incremented.intex);
  17.         statut = pthread_mutex_trylock(&incremented.intex);
  18.         if (statut == 0){
  19.             incremented.entier += compte;
  20.             printf("%ld a augmenté de %d : %d\n", pthread_self(),compte,incremented.entier);
  21.             fflush(stdout);
  22.             compte = 0;
  23.             pthread_mutex_unlock(&incremented.intex);
  24.         }
  25.         compte++;
  26.         pthread_mutex_lock(&incremented.intex);
  27.     }
  28.     pthread_mutex_unlock(&incremented.intex);
  29. }
  30. int main(int argc, char** argv){
  31.     pthread_t thread1, thread2;
  32.     pthread_create(&thread1,NULL,&routine_adding,NULL);
  33.     pthread_create(&thread2,NULL,&routine_adding,NULL);
  34.     pthread_join(thread1,NULL);
  35.     pthread_join(thread2,NULL);
  36.     return EXIT_SUCCESS;
  37. }


 
Ne pas laisser le mutex pouvant être unlock sans lock préalable ... !


Message édité par Shadoko le 26-02-2023 à 10:08:22

---------------
Pourquoi faire simple quand on peut faire compliqué ?
mood
Publicité
Posté le 25-02-2023 à 15:39:25  profilanswer
 

n°2441403
kajoux
Posté le 25-02-2023 à 23:29:03  profilanswer
 

Je pense que c'est parce que tu commences par unlocker un thread qui n'a pas été locké (comportement indéfini).
Comme ça ça a l'air de passer mieux :

Code :
  1. while(incremented.entier < 10000){ //limite
  2.         //pthread_mutex_unlock(&incremented.intex);
  3.         statut = pthread_mutex_trylock(&incremented.intex);
  4.         if (statut == 0){
  5.             incremented.entier += compte;
  6.             printf("%ld a augmenté de %d : %d\n", pthread_self(),compte,incremented.entier);
  7.             fflush(stdout);
  8.             compte = 0;
  9.             pthread_mutex_unlock(&incremented.intex);
  10.         }
  11.         compte++;
  12.         pthread_mutex_lock(&incremented.intex);
  13.         pthread_mutex_unlock(&incremented.intex);
  14.     }
  15.     //pthread_mutex_unlock(&incremented.intex);


Accessoirement la bonne signature pour le callback c'est

static void *routine_adding(void *data)


et il devrait donc renvoyer NULL (ou autre chose…).
Compile avec les warnings -Wall -Wextra.


Message édité par kajoux le 25-02-2023 à 23:38:03
n°2441408
Shadoko
Anciennement Pharmaticien
Posté le 26-02-2023 à 10:05:16  profilanswer
 

Salut kajoux :hello:
 
Merci beaucoup pour ton intervention !
J'essaie de garder le fait de lock le mutex avant de checker le int dans l'assertion du while, car pendant que l'un vérifie, l'autre pourrait faire changer le True/False de (incremented.entier < 10000) sans que le thread vérifiant n'ait la bonne visibilité mémoire.
 
Mais tu as réglé mon problème cela dit car en rajoutant un petit lock au dessus du while dans mon code initial, tout va mieux !
 
Ce qui est curieux c'est que dans les cas de crash, les deux threads avaient réussi à incrémenter à plusieurs répétitions le compteur sans bug jusqu'au crash.
Le premier unlock était donc passé, saurais-tu (ou à bon entendeur, salut) la raison de ce phénomène désormais réglé ?
 
Je n'ai vu nulle part le static dans les tutos qui présentent des routines, est-ce qu'on en a besoin pour autre chose que pour la rendre file scope, ce qu'elle est déjà à mon sens ?  
Merci et à plus !


---------------
Pourquoi faire simple quand on peut faire compliqué ?
n°2441410
kajoux
Posté le 26-02-2023 à 10:27:31  profilanswer
 

Shadoko a écrit :

Ce qui est curieux c'est que dans les cas de crash, les deux threads avaient réussi à incrémenter à plusieurs répétitions le compteur sans bug jusqu'au crash.
Le premier unlock était donc passé, saurais-tu (ou à bon entendeur, salut) la raison de ce phénomène désormais réglé ?


La raison est la manière d'utiliser la mémoire en informatique d'une manière générale, et c'est aussi la raison pour laquelle le comportement est dit "indéfini" (undefined behavior dans les manuels) dans ce cas.
Ça passe un certain nombre de fois, tant qu'il est possible de lire/écrire quelque chose en mémoire sans planter, puis ça finit par planter éventuellement.
C'est aussi la raison pour laquelle les bugs de mauvaise utilisation mémoire peuvent être difficiles à débuguer.
Je n'ai pas essayé de faire tourner ton programme dans Valgrind, mais il dit probablement quelque chose dans ce cas.

Shadoko a écrit :

Je n'ai vu nulle part le static dans les tutos qui présentent des routines, est-ce qu'on en a besoin pour autre chose que pour la rendre file scope, ce qu'elle est déjà à mon sens ?


Il permet en fait d'éviter un warning de déclaration manquante à la compilation, et c'est vrai que dire qu'il fait partie de la signature du callback est un abus de langage.

n°2441418
Shadoko
Anciennement Pharmaticien
Posté le 26-02-2023 à 14:44:22  profilanswer
 

Il faudrait que je me mette au profiling et tout l'outillage pour constater mes premières erreurs dans ma reprise du C, tu fais bien de me le rappeler, au lieu d'encrer des erreurs dans ma tête.
D'accord, je suppose que c'est un warning qui vient avec le -Wall car je ne l'avais pas encore constaté jusque-là.
Merci encore :jap:


---------------
Pourquoi faire simple quand on peut faire compliqué ?
n°2441419
rat de com​bat
attention rongeur méchant!
Posté le 26-02-2023 à 15:19:38  profilanswer
 

obligatoire, surtout mais pas que pour les débutants: -Wall -Wextra
conseillé pour son propre code à mon avis: -Werror
 
Sinon tu peux aussi regarder GDB et Valgrind, très utiles si on les maîtrise (un minimum).

n°2441420
kajoux
Posté le 26-02-2023 à 15:28:27  profilanswer
 

Shadoko a écrit :

D'accord, je suppose que c'est un warning qui vient avec le -Wall car je ne l'avais pas encore constaté jusque-là.


En fait c'est -Wmissing-declarations et il n'est pas dans -Wall ni dans -Wextra, c'est moi qui l'ai ajouté à mes flags  ;)

n°2441421
Shadoko
Anciennement Pharmaticien
Posté le 26-02-2023 à 15:59:45  profilanswer
 

Merci messieurs je me plonge là dedans actuellement :jap:


---------------
Pourquoi faire simple quand on peut faire compliqué ?
n°2441566
masklinn
í dag viðrar vel til loftárása
Posté le 28-02-2023 à 18:27:39  profilanswer
 

Shadoko a écrit :

Ce qui est curieux c'est que dans les cas de crash, les deux threads avaient réussi à incrémenter à plusieurs répétitions le compteur sans bug jusqu'au crash.
Le premier unlock était donc passé, saurais-tu (ou à bon entendeur, salut) la raison de ce phénomène désormais réglé ?


Citation :

If a thread attempts to unlock a mutex that it has not locked or a mutex which is unlocked, undefined behavior results.


UB => opération illégale => aucune raison d'en attendre un comportement logique ou cohérent, ça va dépendre des détails d'implémentation du mutex et de ce que le compilo fait avec.

kajoux a écrit :

La raison est la manière d'utiliser la mémoire en informatique d'une manière générale, et c'est aussi la raison pour laquelle le comportement est dit "indéfini" (undefined behavior dans les manuels) dans ce cas.


Les UB c'est beaucoup plus brutal que ça, la présence d'un UB peut même casser le programme pendant sa compilation. En fait si UB il y a, le programme est considéré comme cassé par définition.


Message édité par masklinn le 28-02-2023 à 18:31:34

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C] Core dumped avec pthread

 

Sujets relatifs
[C] permettre à l’utilisateur de modifier une chaîne de caractères[C#] Class, Struct, c'est quoi maintenant la différence ?
[C#/WPF] PresentMon -> interface graphique ( FPS monitoring )[RESOLU] Algorithme (pour dans un deuxième temps traduire en C)
C Custom Bubble SortLangage C/ projet gestion de véhicules
C++ ou C: compréhension du fonctionement du hardwareLa fenêtre de commande clignote lors du débogage de programmes C++ dan
[C] Refresh d'un fichier ouvert[C#] Code décompilé ne recompile pas...
Plus de sujets relatifs à : [C] Core dumped avec pthread


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR