2017-08-24 16 views
0

私は2つのミューテックスを定義しました:bar_mutex(Nバースレッド間で使用)とwriter_mutex(ウォッチャースレッドのバースレッドで使用)作者のミューテックスはの変数k_totalの奇妙な値を避けるために使用されていますが、グローバル変数を変更していますが、変数が0.0になり、他のスレッドがその値を使っています。 私がwriter_mutexを追加したのを避けるために、問題はまだ続きます。私は間違って何をしていますか?私はコードの重要な部分を貼り付けます。関数move_barのk_totalのこの部分でpthread mutexで予期せぬ動作が発生しました

if (k_total < 1 && b->cm <=20) { 
    b->cm = b->cm + 10; //Usando este valor calculamos el deltak 
    /* printf("\nThread yendo hacia abajo\n"); */ 
    if (b->direction == UP) { 
     b->direction = DOWN; 
     changed_direction = true; 
    } else { 
     changed_direction = false; 
    } 
} else if(k_total > 1 && b->cm >=-20) { 
    b->cm = b->cm - 10; //Usando este valor calculamos el deltak 
    /* printf("\nThread yendo hacia arriba\n"); */ 
    if (b->direction == DOWN) { 
     b->direction = UP; 
     changed_direction = true; 
    } else { 
     changed_direction = false; 
    } 
} 

0の代わりに、 として正しい値を取っている...このを避けるために、私はwriter_mutexを追加しましたが、それはまだ

が動作していませんここで

enter image description here

あなたはグローバル変数KTOTALは、いくつかの01に0として送信されて見ることができますポイント...私はこれを避けようとしています。

私はコードの主要部分を追加します。

void 
start_threads(struct bar* bars) { 
    int i; 
    pthread_t threads[NUM_THREADS + 1]; 
    bars = (struct bar*)malloc(sizeof(struct bar) * NUM_THREADS); 
    init_variables(); 
    pthread_mutex_init(&bar_mutex, NULL); 
    pthread_mutex_init(&write_mutex, NULL); 
    pthread_cond_init(&unstable_state, NULL); 

    for (i = 1; i < NUM_THREADS + 1; i++) { 
     fill_bar(&bars[i - 1], i); 
    } 

    pthread_attr_init(&attr); 
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 
    // creating the 4 threads that handle each bar 
    for (i = 0; i < NUM_THREADS; i++) { 
     pthread_create(&threads[i], &attr, move_bar, (void *)&bars[i]); 
    } 
    //thread used to check if system is stable and change its k_total 
    pthread_create(&threads[NUM_THREADS], &attr, check_stable, (void*)bars); 

    /* Wait for all threads to complete */ 
    for (i=0; i<NUM_THREADS + 1; i++) { 
     pthread_join(threads[i], NULL); 
    } 
} 

void* 
check_stable(void* bars) { 
    struct bar* wires = (struct bar*) bars ; 
    while (true) { 
     pthread_mutex_lock(&write_mutex); 
     k_total = 0.0; 
     for (int i = 0; i < NUM_THREADS; ++i) { 
      k_total += getDeltaKValue(wires[i].cm); 
     } 

     char str[25]; 
     sprintf(str,"deltak=%lf", k_total); 
     doPost("deltak",str); 

     k_total = k_value + k_total; 

     sprintf(str,"kparcial=%lf",k_value); 
     doPost("kparcial",str); 
     sprintf(str,"ktotal=%lf", k_total); 
     doPost("ktotal",str); 
     if ((double)k_total != (double)1.0) { 
      unbalanced = true; 
      pthread_cond_signal(&unstable_state); 
     } else { 
      unbalanced = false; 
     } 
     pthread_mutex_unlock(&write_mutex); 
     sleep(1); 
    } 
} 

void* 
move_bar(void *bar) { 
    struct bar* b = (struct bar*) bar; 
    clock_t start = clock(); 
    bool changed_direction = false; 
    while (true) { 
     pthread_mutex_lock(&bar_mutex); 
     while (unbalanced == false) 
      pthread_cond_wait(&unstable_state, &bar_mutex); 
     pthread_mutex_lock(&write_mutex); 
     if (k_total < 1 && b->cm <=20) { 
      b->cm = b->cm + 10; //Usando este valor calculamos el deltak 
      /* printf("\nThread yendo hacia abajo\n"); */ 
      if(b->direction == UP) { 
       b->direction = DOWN; 
       changed_direction = true; 
      } else { 
       changed_direction = false; 
      } 
     } else if (k_total > 1 && b->cm >=-20) { 
      b->cm = b->cm - 10; //Usando este valor calculamos el deltak 
      /* printf("\nThread yendo hacia arriba\n"); */ 
      if(b->direction == DOWN) { 
       b->direction = UP; 
       changed_direction = true; 
      } else { 
       changed_direction = false; 
      } 
     } 

     k_total = 0.0; 
     for (int i = 0; i < NUM_THREADS; ++i) { 
      k_total += getDeltaKValue(bars[i].cm); 
     } 
     char str[25]; 
     if ((double)k_total != (double)1.0) { 
      unbalanced = true; 
     } else { 
      printf("\nBALANCED"); 
      unbalanced = false; 
     } 

     pthread_mutex_unlock(&write_mutex); 

     if (changed_direction) { 
      sleep(CHANGE_DIRECTION); 
     } 
     sleep(MOVEMENT_TIME); 

     sprintf(str,"id=%ld&cm=%d",b->id, b->cm); 
     doPost("barValue",str); 

     /* printf("\nEnding thread %ld", b->id); */ 
     changed_direction = false; 
     pthread_mutex_unlock(&bar_mutex); 
     sleep(1); 
    } 
    pthread_exit(NULL); 
} 
+1

効率的にデバッグするためには、最初に行うべきことは、すべての**関連する*関数呼び出し(ここでは少なくともpthread _ *()の呼び出し)にエラーチェックとロギングを追加することです。 – alk

+0

この 'sprintf(str、" id =%ld&cm =%d "、b-> id、b-> cm);を' write_mutex'で保護されたクリティカルセクションに移動する方が良いでしょうか? – alk

答えて

0

ここで問題はなかった。そのコードは実際に動作しています。 gdbを使って私は2つのグローバル変数があることを知った同じ名前の2つのmallocを実行していたので、2つの異なる関数でその変数を使っていたので、 ...予期せぬmallocを削除しただけで、すべて正常に動作しました。

関連する問題