1

细节:

我正在实施彼得森算法(如下)以避免竞争条件。我想做的方式是声明一个全局整数变量,并创建线程一和二。每当线程一可以访问全局变量时,它应该打印a并将一个添加到全局变量计数器。当线程二可以访问这个全局变量时,它应该打印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 %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;
}
4

1 回答 1

0

显然,当一个线程重置全局计数器时,另一个线程可能永远不会看到全局计数器达到 eg10,因此它永远不会退出。如果您根本不重置全局计数器,并让它在找到全局计数器(例如 10)时退出线程怎么办?如果您真的想重置计数器,您可以在父(主)线程(这也是您定义全局计数器的位置)中执行此操作。

至于退出线程,您可以简单地从主线程函数返回(这将自行结束线程),pthread_exit从线程内调用,或者您可以phtread_cancel从主函数使用。

于 2014-11-14T13:08:10.210 回答