2009-03-25 32 views
0

次のコードが与えられた場合、特に「 」という前回の3回「You input 7 characters」の原因がわかりますか?セマフォに関する質問

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

テスト入力/出力:

$ 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 

答えて

3

  • sem_post(whileループの終わりに1つ) - >ビン-SEM = 1
  • 試験work_area場合==端(FALSE)
  • 試験work_area == FAST(TRUE)
  • sem_post場合 - >ビン-SEM = 2
  • work_area = Wheeee ...
  • sem_post(whileループの終わりに1つ) - >ビン-SEM = 3
  • テスト== work_areaかの終わり(FALSE)
  • テスト私はそれがfgetsのを呼び出したときにブロックされるまで、メインスレッドが優先権を持っていると思うwork_area = FAST(FALSE)入力

のを待っ

  • 場合(..stdin ..)では、スレッド関数はセマフォトークンを実行して消費することができます。

    ここで何が起こるかの痕跡。

    > 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

    出力は、コードの列挙されたバージョンからのものとは思われない:

    のprintf( "入力テキスト")。

    を生成することはできません。

    入力テキストを。終了するには 'end'を入力してください

    また、2つのスレッド間でループを不規則に制御し、グローバル変数でバインドしています。それはちょうどトラブルを求めている一種の "goto"タイプの構造です...

    ポール。 "FAST" と入力した後

    +0

    スクロールダウン – xtofl

    +0

    これは新しいバージョンに編集されました。(これは編集を許可する問題ですが、履歴を保存しないで、一部の回答は適用されなくなります) –

    +0

    ご迷惑をおかけして申し訳ありません。 – xtofl

    1

    この行はスレッド関数では間違っています。

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

    それはstrlen(work_area)、ないstrlen(work_area-1)であるべきです。

    +0

    そうです。strlenは文字数を返し、ヌルターミネーターは除外します。 – xtofl