题目链接: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; }