当前位置: 首页 > article >正文

c++多线程交替输出

/*
写一个程序:
三个线程交替输出
输入一个数n,例如:
n=4,需要输出队列:01020304
n=5, 需要输出队列:0102030405
线程zero输出0,线程odd输出奇数,线程even输出偶数
注意线程zero一定要等其他两个线程先启动,否则就会出现死锁。
防止多输出0:当odd和even线程都退出了,就没必要继续输出了
*/

#include <bits/stdc++.h>

class Printer {
public:
    Printer(int n) : n(n), i(1), start_odd(false), start_even(false) {}

    void zero(std::function<void(int)> print) {
        while (!(this->start_odd && this->start_even)) {
            ;
        }
        print(0);
        while (true) {
            if (i & 1) {
                cv_odd.notify_one();
            } else {
                cv_even.notify_one();
            }
            {
                std::unique_lock<std::mutex> lock(mtx);
                cv_zero.wait(lock);
            }
            if (!start_even && !start_odd) {
                break;
            }
            print(0);
        }
    };

    void odd(std::function<void(int)> print) {
        while (true) {
            {
                std::unique_lock<std::mutex> lock(mtx);
                start_odd = true;
                cv_odd.wait(lock);
            }
            if (i > n) {
                cv_zero.notify_one();
                break;
            }
            print(i);
            i++;
            cv_zero.notify_one();
            if (i + 1 > n) {
                start_odd = false;
                break;
            }
        }
    };

    void even(std::function<void(int)> print) {
        while (true) {
            {
                std::unique_lock<std::mutex> lock(mtx);
                start_even = true;
                cv_even.wait(lock);
            }
            if (i > n) {
                cv_zero.notify_one();
                break;
            }
            print(i);
            i++;
            cv_zero.notify_one();
            if (i + 1 > n) {
                start_even = false;
                break;
            }
        }
    };

private:
    int n;
    int i;
    bool start_odd, start_even;
    std::mutex mtx;
    std::condition_variable cv_zero, cv_odd, cv_even;
};

void print_func(int x) {
    std::cout << x;
}

int main() {
    int n;
    std::cin >> n;
    Printer printer(n);
    std::thread t1(&Printer::odd, &printer, print_func);
    std::thread t0(&Printer::zero, &printer, print_func);
    std::thread t2(&Printer::even, &printer, print_func);
    t0.join();
    t1.join();
    t2.join();
    return 0;
}

http://www.kler.cn/a/283700.html

相关文章:

  • LabVIEW大数据处理
  • 《Python网络安全项目实战》项目5 编写网站扫描程序
  • Linux 函数在多个地方被同时调用时,函数中的变量如何管理,确保互不影响
  • C++模板特化实战:在使用开源库boost::geometry::index::rtree时,用特化来让其支持自己的数据类型
  • 微服务架构面试内容整理-API 网关-Gateway
  • 在Java中使用ModelMapper简化Shapefile属性转JavaBean实战
  • 启动盘如何复原
  • 【一文详解】内外网文件摆渡系统,解决网间数据安全传输问题
  • 【Python进阶(十二)】——自然语言处理
  • 《华为云 AI:开启智能未来的钥匙》
  • zsh 的补全系统
  • 数字芯片设计验证经验分享(第三部分):将ASIC IP核移植到FPGA上——如何确保性能与时序以完成充满挑战的任务!
  • 【FRP 内网穿透】
  • 【问题分析】SetupWizard退出动画卡住【Android15】
  • 【零知识证明】Groth16
  • GAMES202——作业3 Screen Space Ray Tracing
  • 创建型设计模式-构建器(builder)模式-python实现
  • 35. 交错动画 导航列表项的悬停和聚焦效果
  • Linux下UDP编程
  • InternVL 多模态模型部署微调实践
  • 物联网平台组件2: 平台校验规则
  • 如何构建社区康养养老系统:Java SpringBoot与Vue实战养老管理系统
  • uniapp的锁屏上文字的显示与隐藏
  • ES6中新增的Set方法详解
  • 小资人群“轻社交”需求与创新营销模式——以“2+1 链动模式小程序、AI 智能名片、S2B2C 商城系统”为例
  • 代码随想录Day 28|题目:122.买卖股票的最佳时机Ⅱ、55.跳跃游戏、45.跳跃游戏Ⅱ、1005.K次取反后最大化的数组和