我想了解一些關於並行編程的知識,所以我試圖用一個簡單的例子來實現Peterson的算法,其中一個共享計數器增加了2個線程。我知道彼得森不是最佳的,因爲忙着等待,但我只是爲了學習的原因才嘗試過。Peterson算法的執行錯誤?
我認爲這段代碼的關鍵部分在線程函數add
中共享counter
遞增。所以我在計數器增量之前調用enter_section
函數,之後我調用leave_function
。這部分是錯的嗎?我評估了關鍵部分是否錯誤?問題在於,當這兩個線程完成時,計數器有時會給出不可預期的值。它必須是線程之間的同步問題,但我只是沒有看到它......感謝您的幫助。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int counter; /* global shared counter */
int flag[2] = {0, 0}; /* Variables for Peterson's algorithm */
int turn = 0;
typedef struct threadArgs
{
pthread_t thr_ID;
int num_of_repeats;
int id;
} THREADARGS;
void enter_section (int thread) {
int other = 1 - thread;
flag[thread] = 1;
turn = thread;
while ((turn == thread) && (flag[other] == 1));
return;
}
void leave_section (int thread) {
flag[thread] = 0;
return;
}
void * add (void * arg) {
int i;
THREADARGS * a = (THREADARGS *) arg;
for (i = 0; i < a->num_of_repeats; i++) {
enter_section(a->id);
counter++;
leave_section(a->id);
}
return NULL;
}
int main() {
int i = 1;
pthread_attr_t thrAttr;
THREADARGS threadargs_array[2];
pthread_attr_init (&thrAttr);
pthread_attr_setdetachstate (&thrAttr, PTHREAD_CREATE_JOINABLE);
/* creating 1st thread */
threadargs_array[0].id = 0;
threadargs_array[0].num_of_repeats = 1000000;
pthread_create(&threadargs_array[0].thr_ID, &thrAttr, add, &threadargs_array[0]);
/* creating 2nd thread */
threadargs_array[1].id = 1;
threadargs_array[1].num_of_repeats = 2000000;
pthread_create(&threadargs_array[1].thr_ID, &thrAttr, add, &threadargs_array[1]);
/* free resources for thread attributes */
pthread_attr_destroy (&thrAttr);
/* waiting for 1st thread */
pthread_join (threadargs_array[0].thr_ID, NULL);
printf("First thread is done.\n");
/* waiting for 2nd thread */
pthread_join (threadargs_array[1].thr_ID, NULL);
printf("Second thread is done.\n");
printf("Counter value is: %d \n", counter);
return (EXIT_SUCCESS);
}
在http://bartoszmilewski.com/2008/11/05/who-ordered-memory-fences-on-an-x86/上有關於Peterson同步會發生什麼的描述。雖然我可以發誓,但是'保護區'就足夠了,另外,你需要編譯器的屏障,我將它放在'mfence/sfence'上,並且在'while'循環的每一次迭代中。 – ninjalj 2012-02-27 19:49:20
如果你仍然對此感興趣,可以參考http://stackoverflow.com/questions/11588514/a-tested-implementation-of-peterson-lock-algorithm/11656926#11656926 – ninjalj 2012-07-25 19:26:40