彼得森的算法避免线程之间的竞争条件

时间:2014-11-14 12:49:12

标签: c multithreading algorithm pthreads pthread-join

详细说明:

我正在实施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;
}

1 个答案:

答案 0 :(得分:0)

显然,当一个线程重置全局计数器时,另一个线程可能永远不会看到全局计数器达到例如10,因此它永远不会退出。如果您只是不重置全局计数器,并在它找到全局计数器时让它退出,该怎么办? 10?如果你真的想要重置计数器,你可以在父(主)线程(也是你定义全局计数器的地方)中这样做。

对于退出线程,你可以简单地从主线程函数返回(这将自己结束线程),从线程内调用pthread_exit,或者你可以使用phtread_cancel来自主要功能。