2015-06-26 2 views
0

Как синхронизировать «для» счетчика циклов на многопоточном?Как синхронизировать счетчик циклов «for» в многопоточном режиме?

Если эти программы мульти нить

void Func(int n){ 
for(int i=0; i<n; i++){ //at the same time with other Func() 
    cout << i <<endl; 
} 
} 

void main(){ 
std::thread t1(Func(2)); 
std::thread t2(Func(2)); 
t1.join(); 
t2.join(); 
} 

При выполнении Func() параллельно, я хочу синхронизировать «для» счетчик цикла «я».

Например, программа имеет возможность вывода результата

0 
1 
0 
1 

, но я хочу, чтобы всегда получать результат

0 
0 
1 
1 

Могу ли я это?

+1

Ваша программа имеет возможность распечатывать и другие вещи (например, '00'). Как вы хотите, чтобы счетчик синхронизировался? Вы хотите всегда гарантировать, что сообщения журнала печатаются по порядку? Если да, то зачем вам несколько потоков? – Chad

+0

Это упрощенная программа для запроса вопросов. Моя оригинальная программа имитирует многоагентную систему (Distributed Stochastic Algorithm). В исходной программе я хочу синхронизировать количество проб всех агентов. –

ответ

0

Одним из способов сделать это было бы использование нескольких переменных для потоков для координации действий (в дальнейшем они являются глобальными, просто для простоты).

mutex m; 
condition_variable c; 
static int index = 0; 
static int count = 2; 

index переменная говорит, при котором индекс являются нити, а переменная count говорит сколько потоков в индексе до сих пор.

Теперь вы петля становится:

void Func(int n){ 
for(int i=0; i<n; i++){ //at the same time with other Func() 
    unique_lock<mutex> l(m); 
    c.wait(l, [i](){return index == i;}); 
    cout << i <<endl; 
    if(--count == 0) 
    { 
     ++index; 
     count = 2; 
     c.notify_one(); 
    } 
} 
} 

Вот полный код:

#include <thread> 
#include <mutex> 
#include <condition_variable> 
#include <iostream> 


using namespace std; 


mutex m; 
condition_variable c; 
static int index = 0; 
static int count = 2; 


void Func(int n){ 
for(int i=0; i<n; i++){ //at the same time with other Func() 
    unique_lock<mutex> l(m); 
    c.wait(l, [i](){return index == i;}); 
    cout << i <<endl; 
    if(--count == 0) 
    { 
     ++index; 
     count = 2; 
     c.notify_one(); 
    } 
} 
} 


int main(){ 
std::thread t1(Func, 20); 
std::thread t2(Func, 20); 
t1.join(); 
t2.join(); 
} 
1

Если вы используете OpenMP для потоковой передачи, вы можете использовать оператор #pragma omp barrier.

В C++ 11 вы можете использовать condition_variable, чтобы заблокировать все потоки, пока они не достигнут того же места.

0

Вы можете использовать std:atomic переменной и передать его всем потокам.

void Func(int n, int & i){ 
    for (; i<n; i++){ //at the same time with other Func() 
     cout << i << endl; 
    } 
} 

void main(){ 
    std::atomic<int> counter = 0; 
    std::thread t1(Func, 2, std::ref(counter)); 
    std::thread t2(Func, 2, std::ref(counter)); 
    t1.join(); 
    t2.join(); 
} 

Также вы должны отметить, что способ, которым вы разбиваете свои потоки в вашем примере, неверен. Во-вторых, если вы используете cout в нескольких потоках, каждый cout должен быть защищен с помощью std::mutex, так как cout не является потокобезопасным.

Смежные вопросы