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)原子操作解法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | #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; } |
(2)互斥锁+变量控制方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | #include<mutex> #include<functional> #include<thread> #include<iostream> using namespace std; void printNumber( int value) { cout << value; } class ZeroEvenOdd { private : int n; mutex m; condition_variable cv; 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) { unique_lock<mutex> lock(m); cv.wait(lock, [&] { return flag == 0; }); printNumber(0); if ((i & 0x1) == 0) //注意优先级,如果不确定可以加括号 { flag = 2; } else { flag = 1; } cv.notify_all(); } } void even(function< void ( int )> printNumber) { for ( int i = 2; i <= n; i += 2) { unique_lock<mutex> lock(m); cv.wait(lock, [&] { return flag == 2; }); printNumber(i); flag = 0; cv.notify_all(); } } void odd(function< void ( int )> printNumber) { for ( int i = 1; i <= n; i += 2) { unique_lock<mutex> lock(m); cv.wait(lock, [&] { return flag == 1; }); printNumber(i); flag = 0; cv.notify_all(); } } }; 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; } |
分类:
C++并行编程
, LeetCode题目
posted on 2022-01-05 08:39 xcxfury001 阅读(41) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)