私は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を追加しましたが、それはまだ
あなたはグローバル変数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);
}
効率的にデバッグするためには、最初に行うべきことは、すべての**関連する*関数呼び出し(ここでは少なくともpthread _ *()の呼び出し)にエラーチェックとロギングを追加することです。 – alk
この 'sprintf(str、" id =%ld&cm =%d "、b-> id、b-> cm);を' write_mutex'で保護されたクリティカルセクションに移動する方が良いでしょうか? – alk