我正在实施Peterson的算法(下面)以避免竞争条件。我想要这样做的方法是声明一个全局整数变量,并创建一个和两个线程。每当线程有权访问全局变量时,它应该打印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之前)。 / p>
#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 %d\n",(char *)message,counter);
counter++;
flag[0] = 0;
if(counter == 10){
counter = 1;
printf("exited at func1, with counter %d\n",counter);
exit(0);
}
}
return 0;
}
void *func2(void *message){
while(1){
flag[1] = 1;
turn = 0;
while(flag[0] && turn == 0);
printf("%s %d\n",(char *)message,counter);
counter++;
flag[1] = 0;
if(counter == 10){
counter = 1;
printf("exited at func2, with counter %d\n",counter);
exit(0);
}
}
return 0;
}
答案 0 :(得分:0)
显然,当一个线程重置全局计数器时,另一个线程可能永远不会看到全局计数器达到例如10,因此它永远不会退出。如果您只是不重置全局计数器,并在它找到全局计数器时让它退出,该怎么办? 10?如果你真的想要重置计数器,你可以在父(主)线程(也是你定义全局计数器的地方)中这样做。
对于退出线程,你可以简单地从主线程函数返回(这将自己结束线程),从线程内调用pthread_exit
,或者你可以使用phtread_cancel
来自主要功能。