Подробности:
Я реализую алгоритм Петерсона (ниже), чтобы избежать состояния гонки. Я хочу сделать это так: объявить глобальную целочисленную переменную и создать потоки один и два. Всякий раз, когда поток имеет доступ к глобальной переменной, он должен напечатать 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);
}
Мой код:
EDIT: я понял, что мне нужно поместить оператор 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;
}