2009-03-25 6 views
0

Étant donné le code suivant, pouvez-vous comprendre ce qui a causé "You input 7 characters" est apparu 3 fois en particulier le dernière fois?Question à propos de sémaphore

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <string.h> 
#include <pthread.h> 
#include <semaphore.h> 
void *thread_function(void *arg); 
sem_t bin_sem; 
#define WORK_SIZE 1024 
char work_area[WORK_SIZE]; 
int main(){ 
    int res; 
    pthread_t a_thread; 
    void *thread_result; 
    res = sem_init(&bin_sem,0,0); 
    if (res!=0){ 
     perror("Semaphore initialization failed"); 
     exit(EXIT_FAILURE); 
    } 
    res = pthread_create(&a_thread,NULL,thread_function,NULL); 
    if (res!=0){ 
     perror("Thread creation failed"); 
     exit(EXIT_FAILURE); 
    } 
    printf("Input some text. Enter ‘end’ to finish"); 
    while (strncmp("end",work_area,3)!=0){ 
     if(strncmp(work_area,"FAST",4)==0){ 
      sem_post(&bin_sem); 
      strcpy(work_area,"Wheeee..."); 
     }else{ 
      fgets(work_area,WORK_SIZE,stdin); 
     } 
     sem_post(&bin_sem); 
    } 
    printf("\nWaiting for thread to finish\n"); 
    res = pthread_join(a_thread,&thread_result); 
    if(res!=0){ 
     perror("Thread join failed!"); 
     exit(EXIT_FAILURE); 
    } 
    printf("Thread joined\n"); 
    sem_destroy(&bin_sem); 
    exit(EXIT_SUCCESS); 
} 
void *thread_function(void* arg){ 
    sem_wait(&bin_sem); 
    while(strncmp("end",work_area,3)!=0){ 
     printf("You input %d characters\n",strlen(work_area-1)); 
     sem_wait(&bin_sem); 
    } 
    pthread_exit(NULL); 
} 

Entrée test/sortie:

$ cc -D_REENTRANT thread3a.c -o thread3a -lpthread 
$ ./thread3a 
Input some text. Enter ‘end’ to finish 
Excession 
You input 9 characters 
FAST 
You input 7 characters 
You input 7 characters 
You input 7 characters 
end 
Waiting for thread to finish... 
Thread joined 

Répondre

3

Après avoir tapé "FAST":

  • sem_post (l'une à la fin de la boucle while) -> Poubelle-sem = 1
  • test si work_area == extrémité (FALSE)
  • test si work_area == FAST (TRUE)
  • sem_post -> bin-ETM = 2
  • work_area = Wheeee ...
  • sem_post (l'une à la fin de la boucle while) -> poubelle-sem = 3
  • test si work_area == fin (FAUX)
  • test si work_area = FAST (FAUX)
  • En attente d'entrée

Je pense que le fil conducteur ont la priorité est bloquée jusqu'à ce que quand il appelle fgets (..stdin ..), alors la fonction thread peut s'exécuter et consommer le jeton sémaphore.

Voici une trace de ce qui se passe.

> Input some text. 
    Main thread : 
    work_area = ?; 
    bin_sem = 0; 

    thread function : 
    wait on semaphore; 

< Excession 
    Main thread : 
    work_area = Excession; 
    bin_sem = 1; 

    thread function : 
    work_area == Excession; (!= end) 
> You input 9 characters; (1) 
    bin_sem = 0; 
    wait on semaphore; 

    Main thread : 
    work_area == Excession; (!= end) 
    work_area == Excession; (!= FAST) 
< FAST 
    bin_sem = 1; 
    work_area == FAST; (!= end) 
    work_area == FAST; 
    bin_sem = 2; 
    work_area == Wheeee...; 
    bin_sem = 3; 
    wait on stdin; 

    thread function : 
    work_area == Wheeee...; (!= end) 
> You input 7 characters; (Why seven?) 
    bin_sem = 3-1 = 2; 
> You input 7 characters; (Why seven?) 
    bin_sem = 2-1 = 1; 
> You input 7 characters; (Why seven?) 
    bin_sem = 1-1 = 0; 
    wait on semaphore; 
0

La sortie ne semble pas être de la version indiquée du code:

printf ("Entrée du texte");

ne peut pas produire:

Entrer du texte. Entrez 'end' pour terminer

De même, vous avez plus ou moins partagé la boucle de contrôle de façon erratique entre deux threads, puis les avez liés à une variable globale. C'est une sorte de construction de type "goto" qui demande juste des ennuis ...

Paul.

+0

défiler vers le bas, mec :) – xtofl

+0

Il a été édité à une nouvelle version :-) (C'est le problème de permettre l'édition, mais pas de préserver l'historique, certaines réponses ne s'appliquent plus) –

+0

désolé d'entendre cela. – xtofl

1

Cette ligne est incorrecte dans la fonction de filetage.

printf("You input %d characters\n",strlen(work_area-1)); 

Il devrait être strlen(work_area), pas strlen(work_area-1).

+0

c'est vrai: strlen donne le nombre de caractères, null terminateur exclu. – xtofl

Questions connexes