彼得森算法的错误实现?

我试图学习一些关于并行编程的东西,所以我尝试实现Peterson的算法,这是一个简单的例子,其中一个共享计数器增加2个线程。 我知道彼得森因等待繁忙而不是最佳,但我只是出于学习原因尝试过。

我认为这段代码的关键部分是在线程函数add中共享counter递增的地方。 所以我在计数器递增之前调用enter_section函数,之后调用leave_function 。 这部分错了吗? 我对关键部分的评估错了吗? 问题是当这两个线程完成时,计数器有时会给出一个不可预见的值。 它必须是线程之间的同步问题,但我只是看不到它…感谢您的帮助。

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

你有几个问题:

  • 对变量的访问将受到优化,所以至少你必须声明它们是volatile
  • 像这样在线程之间访问数据而没有POSIX提供的任何锁定数据结构的算法只有在原始操作保证是primefaces操作时才能工作,而这些操作通常不在现代处理器上。 特别是++运算符不是primefaces的。

有几种方法可以解决这个问题,特别是新的C标准C11提供了primefaces基元。 但是,如果这对你来说真正意味着学习并行编程,我强烈建议你首先研究互斥,条件变量等,以了解POSIX的工作原理。