LeetCode 1116. 打印零与奇偶数

题目链接:https://leetcode-cn.com/problems/print-zero-even-odd/

代码参考链接:https://leetcode-cn.com/problems/print-zero-even-odd/solution/c-san-chong-fang-shi-by-desaweis-imvm/

(1)原子操作解法:

#include<functional>
#include<mutex>
#include<thread>
#include<iostream>

using namespace std;

void printNumber(int value)
{
    cout << value;
}

class ZeroEvenOdd
{
private:
    int n;
    atomic<int> flag = 0;

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

    // printNumber(x) outputs "x", where x is an integer.
    void zero(function<void(int)> printNumber)
    {
        for (int i = 1; i <= n; ++i)
        {
            while (flag != 0)
            {
                //告诉内核的调度器如果有其他进程/线程等待在这个CPU上运行,
                //则把CPU让给那些进程,即主动把时间片让出去,但如果本CPU上
                //只有我一个人在运行,没有其他人在等待运行,则调度器还是会
                //选中我来运行,也就是比较gentle的一个出让CPU。如果不执行yield,
                //则如果其他人有运行需求,则我一直尝试占着CPU运行,会导致他们的
                //响应时延变大(等到一个调度时间片后其他进程才有机会运行,现在我
                //yield了他们马上就能运行)。但如果没有其他人有需求,我可以一直占着CPU
                //(但是在过程中执行yield检查是否有其他人有运行需求)。
                //和睡眠的区别是睡眠必然等到指定时间后才重新调度我运行,
                //但yield只在其他人有运行需求的情况下才出让。

                this_thread::yield();
            }

            printNumber(0);
            if ((i & 0x1) == 0)
            {
                flag = 2;
            }
            else
            {
                flag = 1;
            }
        }
    }

    void even(function<void(int)> printNumber)
    {
        for (int i = 2; i <= n; i += 2)
        {
            while (flag != 2)
            {
                this_thread::yield();
            }
            printNumber(i);
            flag = 0;
        }
    }

    void odd(function<void(int)> printNumber)
    {
        for (int i = 1; i <= n; i += 2)
        {
            while (flag != 1)
            {
                this_thread::yield();
            }
            printNumber(i);
            flag = 0;
        }
    }
};

int main()
{
    ZeroEvenOdd myobj(5);
    thread myThread(&ZeroEvenOdd::zero, std::ref(myobj), printNumber);   //保证线程中用的同一个对象
    thread myThread2(&ZeroEvenOdd::even, std::ref(myobj), printNumber);
    thread myThread3(&ZeroEvenOdd::odd, std::ref(myobj), printNumber);

    myThread.join();
    myThread2.join();
    myThread3.join();

    return 0;
}

  

上一篇:uniapp 兼容app和微信程序的动态class 的实现


下一篇:rust的高阶函数