如何在多线程中同步"for"循环计数器?

How to sync "for" loop counter in multithread?

本文关键字:for 循环 计数器 同步 多线程      更新时间:2023-10-16

如何在多线程上同步"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()时,我想同步"for"循环计数器"I"。

例如,程序有可能输出结果

0
1
0
1

但我想总是得到的结果

0
0
1
1

我可以吗?

如果使用OpenMP线程化循环,则可以使用#pragma omp barrier语句。

在C++11中,您可以使用condition_variable来阻塞所有线程,直到它们到达同一位置。

实现这一点的一种方法是为线程使用一些变量来协调事情(在下面,它们是全局变量,只是为了简单起见)。

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

您可以使用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不是线程安全的。