pthreads en C - pthread_exit

Pour une raison que je pense que le fait d'appeler pthread_exit(NULL) à la fin d'une fonction principale de garantir que tous les threads en cours d'exécution (au moins créé dans la fonction principale) pour la fin de course avant main la sortie. Cependant lorsque j'exécute ce code ci-dessous sans appeler les deux pthread_join fonctions (à la fin de main) explicitement j'obtiens une erreur de segmentation, ce qui semble se produire en raison de la main fonction a été fermée avant que les deux threads terminer leur travail, et donc la char tampon n'est plus disponible. Cependant, quand je inclure ces deux pthread_join appels de fonction à la fin de main il fonctionne comme il se doit. Pour garantir que main ne sera pas sortie avant que tous les threads en cours d'exécution ont fini, est-il nécessaire de faire appel à pthread_join explicitement pour tous les threads initialisées directement dans main?

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <assert.h>
#include <semaphore.h>
#define NUM_CHAR 1024
#define BUFFER_SIZE 8
typedef struct {
pthread_mutex_t mutex; 
sem_t full;
sem_t empty;
char* buffer;
} Context;
void *Reader(void* arg) {
Context* context = (Context*) arg;
for (int i = 0; i < NUM_CHAR; ++i) {
sem_wait(&context->full);
pthread_mutex_lock(&(context->mutex));
char c = context->buffer[i % BUFFER_SIZE];
pthread_mutex_unlock(&(context->mutex));
sem_post(&context->empty);
printf("%c", c);
}
printf("\n");
return NULL;
}
void *Writer(void* arg) {
Context* context = (Context*) arg;
for (int i = 0; i < NUM_CHAR; ++i) {
sem_wait(&context->empty);
pthread_mutex_lock(&(context->mutex));
context->buffer[i % BUFFER_SIZE] = 'a' + (rand() % 26);
float ranFloat = (float) rand() / RAND_MAX;
if (ranFloat < 0.5) sleep(0.2);
pthread_mutex_unlock(&(context->mutex));
sem_post(&context->full);
}
return NULL;
}
int main() {
char buffer[BUFFER_SIZE];
pthread_t reader, writer;
Context context;
srand(time(NULL));
int status = 0;
status = pthread_mutex_init(&context.mutex, NULL);
status = sem_init(&context.full,0,0);
status = sem_init(&context.empty,0, BUFFER_SIZE);
context.buffer = buffer;
status = pthread_create(&reader, NULL, Reader, &context);
status = pthread_create(&writer, NULL, Writer, &context);
pthread_join(reader,NULL);   //This line seems to be necessary
pthread_join(writer,NULL);   //This line seems to be necessary
pthread_exit(NULL);
return 0;
}

Si c'est le cas, comment pourrais-je gérer le cas où l'abondance de l'identique fils (comme dans le code ci-dessous) sera créé en utilisant le même identifiant de thread? Dans ce cas, comment puis-je m'assurer que tous les threads ont fini avant main issues de secours? Ai-je vraiment besoin de garder un tableau de NUM_STUDENTS pthread_t identifiants pour être capable de faire cela? Je suppose que je pourrais le faire en permettant à l'Étudiant de fils de signal d'un sémaphore, puis laissez le main fonction d'attente sur le sémaphore, mais il n'y a vraiment pas de moyen plus facile de faire cela?

int main()
{
pthread_t thread;
for (int i = 0; i < NUM_STUDENTS; i++)
pthread_create(&thread,NULL,Student,NULL);  //Threads 
//Make sure that all student threads have finished
exit(0);
}
Notez que sleep() prend un argument entier; votre sleep(0.2) est équivalent à sleep(0) en raison de la conversion implicite. Si vous avez besoin d'un sous-deuxième intervalle du rêve, de l'utilisation (norme POSIX) nanosleep().

OriginalL'auteur Siggi | 2010-07-25