彼得森的算法,以避免线程之间的竞争条件 [英] Peterson's Algorithm to avoid race condition between threads

查看:271
本文介绍了彼得森的算法,以避免线程之间的竞争条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

详细信息:

我在执行Peterson的算法(下同),以避免竞争条件。我想这样做的方式,就是声明一个全局整数变量,并创建线程一和二。每当线程人有访问全局变量应该打印 A 并添加一个全局变量计数器。当线程两人有访问这个全局变量应该打印 B 并添加一个全局变量计数器。这将继续下去,直到全局变量达到一定数目(比方说10)。从那以后,我想要的线程(有史以来两个线程,使得最后除了全局变量的其中)来复位全局变量为1,这两个线程应该退出。我已实施至今还挺code做这项工作,它避免了竞争条件,但我不能离开这两个线程,当计数器达到极限。

问:

  • 我怎么能放弃两个线程,当该计数器达到一个特定的限制。

  • 请告诉我退出线程的适当形式,现在我使用的exit(),我不认为这是非常有效的。

Peterson算法

 布尔标志[2];
INT转;
无效P0()
{
    而(真){
         标志[0] =真;
         转= 1;
         而(标志[1]安培;&放大器;把== 1)/ *什么也不做* /;
         / *临界区* /;
         标志[0] = FALSE;
         /* 余 */;
    }
}

无效P1()
{
     而(真){
          标志[1] =真;
          转= 0;
          而(旗[0]放大器;&放大器;把== 0)/ *什么也不做* /;
          / *临界区* /;
          标志[1] = FALSE;
          /* 余 */
     }
}

 无效的主要()
 {
       标志[0] = FALSE;
       标志[1] = FALSE;
       parbegin(P0,P1);
 }
 

我的code:

修改:我意识到,我必须把if语句,即检查计数器的限定值,应该在关键部分(它改变了标志设置为false之前)

 #包括< stdlib.h中>
#包括< stdio.h中>
#包括< pthreads.h中>


INT计数器= 0;

INT标志[2];
INT转;

void *的FUNC1(无效*);
void *的FUNC2(无效*);

INT主(INT ARGC,字符* argv的[]){

    的pthread_t线程1,线程;
    // INT RT1,RT2;

    标志[0] = 0;
    标志[1] = 0;

    // RT1 = pthread_create的(安培;线程1,NULL,&安培; func1的,一);
    // RT2 = pthread_create的(安培;线程2,NULL,&安培; FUNC2,C);
    在pthread_create(安培;线程1,NULL,&安培; func1的,一);
    在pthread_create(安培;线程2,NULL,&安培; FUNC2,B);

    在pthread_join(线程1,NULL);
    在pthread_join(线程2,NULL);

    返回0;
主要功能} //结束


void *的FUNC1(void *的消息){


    而(1){
        标志[0] = 1;
        转= 1;
        而(标志[1]安培;&放大器;把== 1);
        的printf(%S%D \ N,(字符*)消息,计数器);
        反++;
        标志[0] = 0;

        如果(计数器== 10){
            计数器= 1;
            的printf(退出在FUNC1,用计数器%D \ N,计数器);
            出口(0);
        }
    }
    返回0;
}

void *的FUNC2(void *的消息){

    而(1){
        标志[1] = 1;
        转= 0;
        而(旗[0]放大器;&放大器;把== 0);
        的printf(%S%D \ N,(字符*)消息,计数器);
        反++;
        标志[1] = 0;

        如果(计数器== 10){
            计数器= 1;
            的printf(退出在FUNC2,用计数器%D \ N,计数器);
            出口(0);
        }
    }
    返回0;
}
 

解决方案

显然,当一个线程复位全局计数器,其他线程可能永远也看不到全局计数器达到EG10,所以它永远不会退出。如果你根本不复位全局计数器,并让它线程退出时,它发现了全球反如10?如果你真的想重置计数器,你这样做,在父(主)线程(这也是您定义全局计数器)。

至于退出线程,你可以简单地从主线程函数返回(这将结束自身的线程),叫了pthread_exit 从内螺纹,或您可以使用 phtread_cancel 从main函数。

Details:

I am implementing Peterson's Algorithm(below) to avoid race condition. The way I want to do it, is to declare a global integer variable, and create threads one and two. Whenever the thread one had access to the global variable it should print a and add one to the global variable counter. When the thread two have access to this global variable it should print b and add one to the global variable counter. This should continue until the global variable reaches a certain number(let's say 10). After that I want the thread(which ever of the two threads that makes the last addition to the global variable) to reset the global variable to 1 and both threads should exit. The code that I have implemented so far kinda does the job,it avoids race condition, but I can't exit both threads when counter reaches limit.

Question:

  • How can I quit both threads when the counter reaches a specific limit.

  • Whats the proper form of quitting a thread, right now I am using exit(), which I don't think is very efficient.

Peterson's Algorithm

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

My Code:

EDIT: I realized that I have to put the if-statement, that is checking for the counter limit value, should be in the critical section(before it changes the flag to 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 %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;
}

解决方案

Obviously, when one thread resets the global counter, the other thread may never see the global counter reaching e.g.10, so it will never quit. What if you simply don't reset the global counter, and let it thread quit whenever it finds the global counter e.g. 10? If you really want to reset the counter, you do that in the parent (main) thread (which is also where you define the global counter).

As for quitting a thread, you can either simply return from the primary thread function (this will end the thread by itself), call pthread_exit from within the thread, or you can use phtread_cancel from the main function.

这篇关于彼得森的算法,以避免线程之间的竞争条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆