C++并发学习之一:双线程打印AB或打印奇偶数

一、condition_variable

// 当前线程的执行会被阻塞,直到收到 notify 为止。
void wait (unique_lock<mutex>& lck);

// 当前线程仅在pred=false时阻塞;如果pred=true时,不阻塞。
template <class Predicate>
void wait (unique_lock<mutex>& lck, Predicate pred);

// Unblocks当前正在等待此条件的一个线程。
// 如果没有线程在等待,则函数不执行任何操作。
// 如果有多个线程在等待,它不会指定具体哪个线程。
void notify_one() noexcept;

// Unblocks当前等待此条件的所有线程。
// 如果没有线程在等待,则函数不执行任何操作。
void notify_all() noexcept;

C++多线程04:condition_variable(条件变量)_CHANG_THE_WORLD的博客-CSDN博客

二、奇偶数

创建两个线程,一个打印奇数,一个打印偶数。采用互斥锁(共享资源)+条件变量(唤醒线程)实现。

可以使用一个条件变量或者连个条件变量实现。

#include<iostream>
#include<condition_variable>
#include <mutex>
#include <thread>
std::mutex data_mutex;
std::condition_variable data_var;
std::mutex mut;
std::condition_variable cond1,cond2;
int num=100,g_nums=1;
//双条件变量版本
void thread1() {
    while (true) {
        std::unique_lock<std::mutex> locker(mut);  //会自动解锁
        if (g_nums % 2 == 1 && g_nums <= num)
        {
            std::cout << "Thread1:" << g_nums << std::endl;
            g_nums++;
        }
        cond2.notify_one();
        cond1.wait(locker);
        if (g_nums >= num+1)
            break;
    }
    std::cout << "thread1 done"<< std::endl;
    cond2.notify_one();
}
void thread2() {
    while (true) {
        std::unique_lock<std::mutex> locker(mut);
        if (g_nums % 2 == 0 && g_nums <= num)
        {
            std::cout << "Thread2:" << g_nums << std::endl;
            g_nums++;
        }
        cond1.notify_one();
        cond2.wait(locker);
        if (g_nums >= num + 1)
            break;
    }
    std::cout << "thread2 done" << std::endl;
    cond1.notify_one();
}
int main() {
    std::thread t1(thread1);
    std::thread t2(thread2);
    t1.join();
    t2.join();
    return 0;
}
#include<iostream>
#include<condition_variable>
#include <mutex>
#include <thread>
std::mutex data_mutex;
std::condition_variable data_var;
std::mutex mut;
std::condition_variable cond;
int num=100,g_nums=1;
//单条件变量版本
void thread1() {
    while (true) {
        std::unique_lock<std::mutex> locker(mut);  //会自动解锁
        if (g_nums % 2 == 1 && g_nums <= num)
        {
            std::cout << "Thread1:" << g_nums << std::endl;
            g_nums++;
        }
        cond.notify_one();//唤醒另外的一个进程
        cond.wait(locker);//阻塞当前进程
        if (g_nums >= num+1)
            break;
    }
    std::cout << "thread1 done"<< std::endl;
    cond.notify_one();
}
void thread2() {
    while (true) {
        std::unique_lock<std::mutex> locker(mut);
        if (g_nums % 2 == 0 && g_nums <= num)
        {
            std::cout << "Thread2:" << g_nums << std::endl;
            g_nums++;
        }
        cond.notify_one();//唤醒另外一个进程
        cond.wait(locker);
        if (g_nums >= num + 1)
            break;
    }
    std::cout << "thread2 done" << std::endl;
    cond.notify_one();
}
int main() {
    std::thread t1(thread1);
    std::thread t2(thread2);
    t1.join();
    t2.join();
    return 0;
}

三、循环打印AB

注意wait有两种使用方式,参考:C++多线程04:condition_variable(条件变量)_CHANG_THE_WORLD的博客-CSDN博客

#include<iostream>
#include<condition_variable>
#include <mutex>
#include <thread>
std::mutex data_mutex;
std::condition_variable data_var;
bool flag = true;//通过flag决定两个线程是否阻塞

void printA()
{
    while(1)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::unique_lock<std::mutex> lck(data_mutex) ;
        data_var.wait(lck,[]{return flag;});//false才阻塞,true不阻塞
        std::cout<<"thread: "<< std::this_thread::get_id() << "   printf: " << "A" <<std::endl;
        flag = false;
        data_var.notify_one();
    }
}

void printB()
{
    while(1)
    {
        std::unique_lock<std::mutex> lck(data_mutex) ;
        data_var.wait(lck,[]{return !flag;});
        std::cout<<"thread: "<< std::this_thread::get_id() << "   printf: " << "B" <<std::endl;
        flag = true;
        data_var.notify_one();
    }
}

int main()
{
    std::thread tA(printA);
    std::thread tB(printB);
    tA.join();
    tB.join();
    return 0;
}



#include<iostream>
#include<condition_variable>
#include <mutex>
#include <thread>
std::mutex data_mutex;
std::condition_variable data_var;

void printA()
{
    while(1)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));//类似于消费者
        std::unique_lock<std::mutex> lck(data_mutex) ;//lck会自动解锁
        std::cout<<"thread: "<< std::this_thread::get_id() << "   printf: " << "A" <<std::endl;
        data_var.notify_one();
        data_var.wait(lck);
    }
}

void printB()
{
    while(1)
    {
        std::this_thread::sleep_for(std::chrono::seconds(2));//类似于生产者
        std::unique_lock<std::mutex> lck(data_mutex) ;
        std::cout<<"thread: "<< std::this_thread::get_id() << "   printf: " << "B" <<std::endl;
        data_var.notify_one();
        data_var.wait(lck);
    }
}

int main()
{
    std::thread tA(printA);
    std::thread tB(printB);
    tA.join();
    tB.join();
    return 0;
}

//错误程序
#include<iostream>
#include<condition_variable>
#include <mutex>
#include <thread>

class print_a_b{
public:
    print_a_b(){};
    void printA()
    {
        while(1)
        {
            std::this_thread::sleep_for(std::chrono::seconds(1));//类似于消费者
            std::unique_lock<std::mutex> lck(data_mutex) ;//lck会自动解锁
            std::cout<<"thread: "<< std::this_thread::get_id() << "   printf: " << "A" <<std::endl;
            data_var.notify_one();
            data_var.wait(lck);
        }
    }

    void printB()
    {
        while(1)
        {
            std::this_thread::sleep_for(std::chrono::seconds(2));//类似于生产者
            std::unique_lock<std::mutex> lck(data_mutex) ;
            std::cout<<"thread: "<< std::this_thread::get_id() << "   printf: " << "B" <<std::endl;
            data_var.notify_one();
            data_var.wait(lck);
        }
    }

private:
    std::mutex data_mutex;
    std::condition_variable data_var;
};

int main()
{
    print_a_b A,B;
    std::thread tA(A.printA());//传对象,而不是函数结果
    std::thread tB(B.printB());
    tA.join();
    tB.join();
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值