详细信息:
我正在实现彼得森算法(下图)以避免竞争条件。我想这样做的方法是声明一个全局整数变量,并创建线程一和线程二。每当线程可以访问全局变量时,它应该打印a
并将一个添加到全局变量计数器中。当线程 2 可以访问此全局变量时,它应该打印b
并将一个添加到全局变量计数器中。这应该持续到全局变量达到某个数字(假设 10)。之后,我希望线程(最后一次添加到全局变量的两个线程中的哪个线程)将全局变量重置为 1,并且两个线程都应该退出。到目前为止,我实现的代码可以完成这项工作,它避免了竞争条件,但是当计数器达到限制时,我无法退出两个线程。
问题:
-
当计数器达到特定限制时,如何退出两个线程。
-
退出线程的正确形式是什么,现在我正在使用 exit(),我认为这不是很有效率。
彼得森算法
boolean flag [2];
int turn;
void P0()
{
while (true) {
flag [0] = true;
turn = 1;
while (flag [1] && turn == 1) /* do nothing */;
/* critical section */;
flag [0] = false;
/* remainder */;
}
}
void P1()
{
while (true) {
flag [1] = true;
turn = 0;
while (flag [0] && turn == 0) /* do nothing */;
/* critical section */;
flag [1] = false;
/* remainder */
}
}
void main()
{
flag [0] = false;
flag [1] = false;
parbegin (P0, P1);
}
我的代码:
编辑:我意识到我必须将 if 语句,即检查计数器限制值,应该放在关键部分(在它将标志更改为 false 之前)。
#include<stdlib.h>
#include<stdio.h>
#include<pthread.h>
int counter = 0;
int flag[2];
int turn;
void *func1(void *);
void *func2(void *);
int main(int argc,char *argv[]){
pthread_t thread1,thread2;
//int rt1,rt2;
flag[0] = 0;
flag[1] = 0;
//rt1 = pthread_create(&thread1,NULL,&func1,"a");
//rt2 = pthread_create(&thread2,NULL,&func2,"c");
pthread_create(&thread1,NULL,&func1,"a");
pthread_create(&thread2,NULL,&func2,"b");
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
return 0;
}// End of main function
void *func1(void *message){
while(1){
flag[0] = 1;
turn = 1;
while(flag[1] && turn == 1);
printf("%s %dn",(char *)message,counter);
counter++;
flag[0] = 0;
if(counter == 10){
counter = 1;
printf("exited at func1, with counter %dn",counter);
exit(0);
}
}
return 0;
}
void *func2(void *message){
while(1){
flag[1] = 1;
turn = 0;
while(flag[0] && turn == 0);
printf("%s %dn",(char *)message,counter);
counter++;
flag[1] = 0;
if(counter == 10){
counter = 1;
printf("exited at func2, with counter %dn",counter);
exit(0);
}
}
return 0;
}
显然,当一个线程重置全局计数器时,另一个线程可能永远不会看到全局计数器达到例如 10,因此它永远不会退出。如果您只是不重置全局计数器,并在找到全局计数器(例如 10)时让它线程退出怎么办?如果确实要重置计数器,请在父(主)线程(也是定义全局计数器的位置)中执行此操作。
至于退出线程,您可以简单地从主线程函数返回(这将自行结束线程),从线程内部调用pthread_exit
,或者您可以使用 main 函数中的phtread_cancel
。