首页 > 解决方案 > 只允许某些线程并行执行

问题描述

我有一个类的两个成员函数,比如foo1foo2

foo1接收一个字符串label和一个data作为输入和调用foo2

class MyClass {
public:
void foo1(int data, std::string label) {
  // do stuff
  foo2();
}
void foo2(void) {}
  
};

现在,我希望能够为并行执行创建线程foo1,但只有不同labels 的线程才能并行执行。

如果labelA调用了一个线程,而另一个相同标签的线程仍在运行,则第一个线程必须等待第二个线程结束其执行。

// t1 and t2 should run in parallel, t3 should wait for t1 to end
std::thread t1(foo1, "LabelA", 5);
std::thread t2(foo1, "LabelB", 8);
std::thread t3(foo1, "LabelA", 1);

这是一个已知的并发问题吗?我找不到解决此问题的方法,因为在这种情况下,互斥锁似乎是不够的。

总之,我的问题是:如何只允许某些“类型的线程”并行执行?

标签: c++multithreading

解决方案


互斥锁正是您想要的。您只需要每个 1 个互斥锁label,例如在一个std::maplabel. 然后,foo1()可以锁定std::mutex指定的label,完成后解锁,例如:

std::map<std::string, std::mutex> locks;
     
class MyClass {
public:
    void foo1(int data, std::string label)
    {
        std::lock_guard<std::mutex> g(locks[label]);
     
        // do stuff
        foo2();
    }
     
    void foo2()
    {
        ...
    }
};
// only one these "LabelA" threads should run in parallel with "LabelB" thread,
// the other "LabelA" thread should wait for the earlier "LabelA" thread to end

locks["LabelA"];
locks["LabelB"];

std::thread t1(&MyClass::foo1, &SomeMyClassObj, 5, "LabelA");
std::thread t2(&MyClass::foo1, &SomeMyClassObj, 8, "LabelB");
std::thread t3(&MyClass::foo1, &SomeMyClassObj, 1, "LabelA");

...

演示


推荐阅读