Question

Étant donné le code suivant, vous pouvez comprendre ce qui a causé « Vous entrez 7 caractères » arriviez 3 fois en particulier les dernière fois?

#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 de 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
Était-ce utile?

La solution

Après avoir tapé "FAST":

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

Je pense que le thread principal ont la priorité est bloquée jusqu'à ce que lorsqu'il appelle fgets (.. stdin ..), la fonction de fil peut fonctionner et consommer le jeton sémaphores.

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;

Autres conseils

Cette ligne ne va pas dans la fonction fil.

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

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

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

printf ( "Entrée du texte");

ne peut pas produire:

Saisie du texte. Entrez « end » pour terminer

En outre, vous avez plus ou moins boucle vous contrôler de façon erratique divisée entre deux fils, puis les liaient avec une variable globale. Il est une sorte de construction de type « goto » qui vient d'avoir des ennuis ...

Paul.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top