这个类的主要功能就是,当多个线程运行的时候,count满足一定的条件的时候(这里为0),部分线程才开始工作。
具体如下:
#include <atomic>
#include <condition_variable>
#include <mutex>
#ifdef __cplusplus
extern "C" {
#endif
#include <pthread.h>
#include <unistd.h>
#ifdef __cplusplus
}
#endif
class CountDownLauch {
public:
CountDownLauch(const int n) : count(n) {}
~CountDownLauch() = default;
void countDown() {
std::unique_lock<std::mutex> lock(m_mutex);
count--;
printf("conut -- %d\n", count);
if (count <= 0)
m_cv.notify_all();
}
void waitCD() {
std::unique_lock<std::mutex> lock(m_mutex);
m_cv.wait(lock, [this]() { return this->count <= 0; });
printf("cv wait return ,count=%d\n", count);
}
int getCount() {
std::unique_lock<std::mutex> lock(m_mutex);
return count;
}
private:
std::mutex m_mutex;
std::condition_variable m_cv;
int count{0};
};
void *threadCb1(void *p) {
CountDownLauch *ptr = reinterpret_cast<CountDownLauch *>(p);
while (ptr->getCount() > 0) {
ptr->countDown();
sleep(1);
// printf("pthread call\n");
// printf("pthread exit.\n");
// pthread_exit(nullptr);
}
return nullptr;
}
void *threadCb2(void *p) {
CountDownLauch *ptr = reinterpret_cast<CountDownLauch *>(p);
// while (true)
{
ptr->waitCD();
sleep(1);
// printf("pthread call\n");
// printf("pthread exit.\n");
// pthread_exit(nullptr);
}
return nullptr;
}
int main() {
setbuf(stdout, nullptr);
CountDownLauch c{10};
pthread_t t = 0;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, 1);
pthread_create(&t, &attr, threadCb2, (void *)(&c));
pthread_t t2 = 0;
pthread_create(&t2, nullptr, threadCb1, &c);
pthread_join(t2, nullptr);
pthread_attr_destroy(&attr);
}
这是对信号变量的非常有用的一个用法,还有一个用法是消费者生产者模式:
class ConPro {
public:
void produce() {
std::unique_lock<std::mutex> lock(m_mutex);
count += 20;
printf("conut -- %d\n", count);
m_cv.notify_all();
while (count > 100) {
m_cv.wait(lock);
}
}
void consume() {
std::unique_lock<std::mutex> lock(m_mutex);
while (count <= 0) {
m_cv.wait(lock);
}
printf("cv wait return ,count=%d\n", count);
count--;
m_cv.notify_all();
}
private:
std::mutex m_mutex;
std::condition_variable m_cv;
int count{0};
};
void test2() {
ConPro cp;
auto cb1 = [&cp]() {
while (true) {
cp.consume();
}
};
auto cb2 = [&cp]() {
while (true) {
cp.produce();
sleep(1);
}
};
std::thread t1(cb1);
if (t1.joinable()) {
t1.detach();
}
std::thread t2(cb2);
if (t2.joinable())
t2.join();
}
int main() {
setbuf(stdout, nullptr);
test2();
}