Frage

Mit dem folgenden Code gegeben, können Sie herausfinden, was die Ursache „Sie Eingang 7 Zeichen“ auftauchten 3 mal vor allem der letztes Mal?

#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);
}

Test Eingang / Ausgang:

$ 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
War es hilfreich?

Lösung

Nach der Eingabe "FAST":

  • sem_post (die am Ende der while-Schleife) -> bin-SEM = 1
  • Test, wenn work_area == Ende (FALSCH)
  • Test, wenn work_area == FAST (TRUE)
  • sem_post -> bin-sem = 2
  • work_area = Wheeee ...
  • sem_post (die am Ende der while-Schleife) -> bin-SEM = 3
  • Test, wenn work_area == Ende (FALSCH)
  • Test, wenn work_area = FAST (FALSCH)
  • Warten auf Eingabe

ich glaube, das Hauptthread hat die Priorität bis blockiert wird, wenn es ruft fgets (.. stdin ..), dann wird die Thread-Funktion kann die Semaphore Token ausführen und verbrauchen.

Hier ist eine Spur von dem, was passiert.

> 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;

Andere Tipps

Diese Zeile ist falsch in der Thread-Funktion.

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

Es sollte strlen(work_area) werden, nicht strlen(work_area-1).

Die Ausgabe erscheint nicht von der aufgeführten Version des Codes zu sein:

printf ( "Input some text");

kann nicht produzieren:

Input einige Text. Geben Sie ‚Ende‘ beenden

Auch haben Sie mehr oder weniger Split Sie Schleife erratisch zwischen zwei Threads zu steuern und banden sie dann mit einer globalen Variablen. Es ist eine Art von „goto“ Konstruktion, die für Ärger nur gefragt wird ...

Paul.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top