Я пытаюсь провести строгое чередование двух процессов, но я не уверен, как объявить критическую область и некритическую область. Вот код, который у меня есть:
#include <iostream>
#include <pthread.h>int count;
int turn = 0; // Shared variable used to implement strict alternationvoid* myFunction(void* arg)
{
int actual_arg = *((int*) arg);
for(unsigned int i = 0; i < 10; ++i) {
while(1)
{
while(turn != 0)
{
critical_region_0();
turn = 1;
non_critical_region_0();
}
}
// Beginning of the critical region
count++;
std::cout << "Thread #" << actual_arg << " count = " << count <<
std::endl;
// End of the critical region
while(0)
{
while(turn != 1)
{
critical_region_1();
turn = 0
non_critical_region_1();
}
}}
pthread_exit(NULL);
}
int main()
{
int rc[2];
pthread_t ids[2];
int args[2];
count = 0;
for(unsigned int i = 0; i < 2; ++i) {
args[i] = i;
rc[i] = pthread_create(&ids[i], NULL, myFunction, (void*) &args[i]);
}
for(unsigned int i = 0; i < 2; ++i) {
pthread_join(ids[i], NULL);
}
std::cout << "Final count = " << count << std::endl;
pthread_exit(NULL);
}
Я знаю, что критические области и некритические области написаны так, как будто они являются методом, но я использую их в качестве заполнителей. Есть ли способ провести строгое чередование без использования этих методов?
Вот как должен выглядеть вывод.
Thread #0 count = 1
Thread #1 count = 2
Thread #0 count = 3
Thread #1 count = 4
Thread #0 count = 5
Thread #1 count = 6
Thread #0 count = 7
Thread #1 count = 8
Thread #0 count = 9
Thread #1 count = 10
Thread #0 count = 11
Thread #1 count = 12
Thread #0 count = 13
Thread #1 count = 14
Thread #0 count = 15
Thread #1 count = 16
Thread #0 count = 17
Thread #1 count = 18
Thread #0 count = 19
Thread #1 count = 20
Final count = 20
Вывод, который мне удалось получить, — сначала весь поток 1, а затем поток 0.
Я думаю, что это классическое место для сигналов. Каждая функция, управляющая потоком, выглядит так (например, поток 1)
while( ... ) {
...
pthread_cond_signal(thread1_done_work);
pthread_cond_wait(thread_2_done_work);
}
где обе рабочие переменные являются глобальными типами pthread_cond_t
— Я думаю, что с двумя удобнее читать, но вам не нужно использовать два (на ум приходит реализация мьютекса).
Поток 2 нуждается в условии ожидания, как только он запускается. Вот некоторые детали:
https://linux.die.net/man/3/pthread_cond_wait
https://linux.die.net/man/3/pthread_cond_signal
По сути, каждый поток сигнализирует, что это сделано (это блокирует, пока другой поток не будет готов перехватить это), а затем ожидает другого потока. Таким образом, они «говорят» мой ход, ваш ход и т. Д. Если вы настаиваете на использовании одной и той же функции для обоих потоков, вы можете изменять условные переменные в качестве аргументов (меняются местами для потока 2 относительно 1).
И последнее небольшое замечание — это несколько противоречит всей цели создания потоков.
Других решений пока нет …