2016-10-16 1 views
-1
int err = pthread_create(&p, NULL, pro, (void*)1); 

Chaque fois que je lance le programme que je continue à obtenir une erreur de segmentation, je l'ai lu et compris qu'un thread essaie de lire et OS bloque. J'ai regardé dans le code pour trouver l'erreur, mais j'ai du mal parce que je n'ai pas un débogueur qui fonctionne bien avec C.défaut de segmentation (core dumped)

Quelqu'un peut-il m'aider avec ce problème?

Répondre

2

En utilisant GDB (vous devriez l'utiliser) vous pouvez obtenir de bonnes informations lorsque votre programme plante.

d'abord construire le programme avec "-g"

gcc file.c -lpthread -g 

Lancez ensuite gdb.

Vous verrez ceci:

Thread 2 "a.out" received signal SIGSEGV, Segmentation fault. 
[Switching to Thread 0x7ffff781e700 (LWP 8082)] 
0x0000000000400b94 in produce (arg=0x1) at test.c:84 
84  int id = *(int*) arg; 

De là, il est assez évident que la ligne coupable est:

int id = *(int*) arg; 

Voyons voir exactement ce que vous faites ici:

Vous voulez pour obtenir ce paramètre afin que vous puissiez l'utiliser. C'est exact ...

regarder cependant la façon dont vous avez passé le paramètre à votre fonction:

int err = pthread_create(&producer_thread1, NULL, produce, (void*)1); 

Vous prenez la valeur « 1 », et jetant à annuler *. Pourquoi pas ... même si vous ne voudriez jamais vraiment le faire sauf quelques cas particuliers peut-être ... Mais dans votre cas précis ce n'est absolument pas ce que vous voulez, pourquoi? Parce qu'à l'intérieur de la fonction Produire, vous pensez que c'est un pointeur vers et int, mais ce n'est pas le cas! c'est un nombre (1) converti en un vide *, donc sur votre système il a été casté à la valeur (1) écrite sur 64bits mais c'est toujours un 1. Donc quand vous essayez de le déréférencer, vous obtenez une segmentation faute.

essayer de déclarer les valeurs thoose comme variables et transmettre leur adresse à la fonction pthread_create (tous)

EDIT

int err = pthread_create(&producer_thread1, NULL, produce, (void*)1); 

deviendrait:

int err = pthread_create(&producer_thread1, NULL, produce, (void*)&one); 

où la variable "un" pourrait être une variable globale comme ceci:

int one = 1; 

mais il peut également s'agir d'un int alloué ou de tout int qui a une adresse que vous choisissez .. il suffit de ne pas passer une valeur qui n'est pas et adresse et gérer comme si elle était.

Espérons que cela peut aider.

+0

Tout ce qui était à l'intérieur et dans la plupart des autres parties m'a été donné par le professeur et on m'a dit de ne rien changer à l'intérieur. Je suis seulement autorisé à changer 'void * produire (void * arg)' et 'void * consommer (void * arg)'.Terminal a mentionné que l'erreur avait quelque chose à voir avec pthread_create! Certains de mes camarades de classe ont dit qu'ils n'ont eu aucune de ces erreurs! – ben

+0

Vous pouvez essayer de lancer arg sur un long long int ... mais ce n'est PAS comme ça que vous passeriez des paramètres à pthead_create. Le code original et la "technique" que je vous donne ici sont BAD dans votre cas d'utilisation. Vous obtiendrez juste des erreurs et du code moins lisible. Mais si vous avez aussi pour votre professeur .. –

+1

@HectorRoussille Je vais changer la fonction create_thread. Donc, juste pour clarifier ce que vous essayez de me dire, vous voulez que je change '(void *) 1' en une variable. Par exemple 'int a = 1,' 'et puis à l'intérieur create_thread (..., (void *) (intptr_t) a;.' Se passerait-il que – ben