两个线程交替打印的各种解决方法

 

题目https://leetcode-cn.com/problems/print-foobar-alternately/

 

方法1:模仿信号量机制,使用两个整数来控制先后执行顺序。

class FooBar {
private:
	int n;

public:
	FooBar(int n) {
		this->n = n;

	}

	void foo(function<void()> printFoo) {

		for (int i = 0; i < n; i++) {

			// printFoo() outputs "foo". Do not change or remove this line.
		//相当于信号量的wait操作:	
                while (s2 < 1) {
				std::this_thread::sleep_for(std::chrono::milliseconds(1));
			}
			s2--;  

			printFoo();
                //相当于信号量的inc操作:	
			s1++;
		}
	}

	void bar(function<void()> printBar) {

		for (int i = 0; i < n; i++) {

			// printBar() outputs "bar". Do not change or remove this line.
			while (s1 < 1) {
				std::this_thread::sleep_for(std::chrono::milliseconds(1));//注释掉会超时错误
			}
			s1--;

			printBar();
			s2++;
		}
	}

private:
	 std::atomic<int> s1=0; //场景较为简单,不使用原子类型也可以
	 std::atomic<int> s2=1;
	int s1 = 0;
	int s2 = 1;
};

方法2:借助c++ std::mutex锁,本质上与方法1一样,时间消耗略增多,空间消耗也略增多。

class FooBar {
private:
    int n;

public:
    FooBar(int n) {
        this->n = n;
        m1.lock();
        
    }

    void foo(function<void()> printFoo) {
        
        for (int i = 0; i < n; i++) {
            
        	// printFoo() outputs "foo". Do not change or remove this line.
           
            m2.lock();
        	printFoo();
            m1.unlock();
        }
    }

    void bar(function<void()> printBar) {
        
        for (int i = 0; i < n; i++) {
            
        	// printBar() outputs "bar". Do not change or remove this line.
            m1.lock();
        	printBar();
            m2.unlock();
        }
    }

private:
  std::mutex m1;
  std::mutex m2;
};

方法3:借助条件变量, 时间和空间效率,完胜前两种方法:

C++条件变量--std::condition_variable的使用方法:https://blog.csdn.net/qq_35865125/article/details/108859681

class FooBar {
private:
    int n;

public:
    FooBar(int n) {
        this->n = n;

        m_foo_printed = false;
        m_bar_printed = true;
    }

    void foo(function<void()> printFoo) {

        for (int i = 0; i < n; i++) {

            unique_lock<mutex> lck(m_mtx);

            while(!m_bar_printed)
            {
                m_cv.wait(lck);  //等bar打印完
            }

            // printFoo() outputs "foo". Do not change or remove this line.
            printFoo();

            m_foo_printed = true;
            m_bar_printed = false;
            m_cv.notify_one();
        }
    }

    void bar(function<void()> printBar) {

        for (int i = 0; i < n; i++) {

            unique_lock<mutex> lck(m_mtx);

            while(!m_foo_printed)
            {
                m_cv.wait(lck);  //等foo打印完
            }

            // printBar() outputs "bar". Do not change or remove this line.
            printBar();

            m_bar_printed = true;
            m_foo_printed = false;
            m_cv.notify_one();
        }
    }

private:
    mutex m_mtx;
    condition_variable m_cv;
    bool m_foo_printed; //foo打印完了
    bool m_bar_printed; //bar打印完了
};

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

First Snowflakes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值