c++ 多线程编程demo

最佳实践:(摘录《c++高级编程 27.13 线程设计和最佳实践》)

  1. 使用并行标准库算法
  2. 终止应用程序前,确保所有thread对象都不是可joinable的
  3. 最好的同步就是没有同步(各线程只读取共享数据,不写入)
  4. 尝试使用单线程的所有权模式(一个线程拥有数据的独有权,处理完再传递给另一个线程)
  5. 在可能时使用原子类型和操作
  6. 使用锁保护可变的共享数据
  7. 尽快释放锁
  8. 不要手动获取多个锁,应该使用std::lock或std::try_lock(获取多个锁顺序要一致)
  9. 使用多线程的分析器
  10. 使用RAII锁对象(lock_guard、unique_loce、shared_lock、scoped_lock)
  11. 了解调试器的对线程支持特性
  12. 使用线程池,不动态创建和销毁大量线程
  13. 使用高级线程库(TBB、PPL)

I/O多路复用
https://zhuanlan.zhihu.com/p/115220699

几个多线程常用demo代码:

#include <atomic>
#include <latch>
#include <barrier>
#include <semaphore>
#include <future>
#include <iostream>
#include <thread>
#include <chrono>using namespace std::chrono_literals;void counter(int id, int numIterations)
{for (int i{ 0 }; i < numIterations; i++) {std::cout << "Counter " << id << " has value " << i << std::endl;}
}void increment(std::atomic<int>& counter)
{for (int i{ 0 }; i < 100; i++) {++counter;std::this_thread::sleep_for(std::chrono::microseconds(1));}
}void increment_ref(int& counter)
{std::atomic_ref<int> atomicCounter{ counter };for (int i{ 0 }; i < 100; i++) {++atomicCounter;std::this_thread::sleep_for(std::chrono::microseconds(1));}
}class Counter
{
public:Counter(int id, int numIterations) :m_id{ id }, m_numIterations{ numIterations } {}void operator()() const noexcept{for (int i{ 0 }; i < m_numIterations; ++i) {std::lock_guard lock{ ms_mutex };std::cout << "Counter " << m_id << " has value " << i << std::endl;}}void process() {for (int i{ 0 }; i < m_numIterations; ++i) {std::unique_lock lock{ ms_timed_mutex ,200ms };if (lock) {std::cout << "Counter " << m_id << " has value " << i << std::endl;}}}private:int m_id;int m_numIterations;inline static std::mutex ms_mutex;inline static std::timed_mutex ms_timed_mutex;
};int k;
thread_local int n;void counter_k(int id)
{std::cout << std::format("Thread {}:k={},n={}\n ",id, k,n);++k;++n;std::cout << std::format("Thread {}:k={},n={}\n ", id, k, n);
}void doSomeWork()
{throw std::runtime_error{" Exception from thread"};
}void threadFunc(std::exception_ptr& err)
{try {doSomeWork();}catch (...) {err = std::current_exception();}
}void doWorkInThread()
{std::exception_ptr error;std::thread te{ threadFunc,std::ref(error) };te.join();if (error) {std::rethrow_exception(error);}
}int main()
{std::cout.sync_with_stdio(false);std::thread t1{ counter, 1, 6 };std::thread t2{ counter, 2, 4 };t1.join();t2.join();std::thread t3{ Counter{3, 10} };t3.join();Counter c{ 4, 5 };std::thread t4{ std::ref(c) };t4.join();int id{ 5 };int numIterations{ 6 };std::thread t5{ [id, numIterations]() {for (int i{ 0 }; i < numIterations; ++i) {std::cout << "Counter " << id << " has value " << i << std::endl;}} };t5.join();Counter c1{ 6, 5 };std::thread t6{ &Counter::process,&c1 };t6.join();std::thread t11{ counter_k ,1};t11.join();std::thread t12{ counter_k ,2};t12.join();// jthread c++20 ,destory finish joinstd::jthread job{ [](std::stop_token token) {while (!token.stop_requested()) {std::cout << "running\n";Sleep(100);}}};Sleep(1000);job.request_stop();std::cout << "stop running\n";// catch error from threadtry {doWorkInThread();}catch (const std::exception& e) {std::cout << "Main thread caught:" << e.what()<< std::endl;}// atomicstd::atomic<int> counter{ 0 };int con{0};std::vector<std::thread> threads;for (int i{ 0 }; i < 10; ++i) {threads.push_back(std::thread{ increment,std::ref(counter) });threads.push_back(std::thread{ increment_ref,std::ref(con) });}for (auto& t : threads) {t.join();}std::cout << "Result:" << counter << std::endl;std::cout << "Result:" << con << std::endl;std::atomic<int> value{0};std::thread job1{ [&value]() {std::cout << "wait value:" << value << std::endl;value.wait(value);std::cout << "value:" << value << std::endl;} };std::this_thread::sleep_for(std::chrono::seconds(2));value = 1;value.notify_all();job1.join();// 同步控制 latchstd::latch startlatch{10};std::vector<std::jthread> threads_;for (int i{ 0 }; i < 10;i++) {threads_.push_back(std::jthread{ [&startlatch, id = i]() {std::this_thread::sleep_for(20ms);std::cout << "latch:" << id << std::endl;startlatch.count_down();startlatch.wait();std::cout << "latch:finish" << id << std::endl;}});}startlatch.wait();std::cout << "latch:finish";threads_.clear();// 同步控制 latchconst auto workers = { "anil", "busara", "carl" };auto on_completion = []() noexcept {static const char* phase = "... done\n" \"Cleaning up...\n";std::cout << phase;phase = "... done\n";};std::barrier sync_point(workers.size(),on_completion);auto work = [&](const std::string& name) {std::string product = "  " + name + " worked\n";std::cout << product; // ok, op<< call is atomicsync_point.arrive_and_wait();product = "  " + name + " cleaned\n";std::cout << product;sync_point.arrive_and_wait();};std::cout << "Starting...\n";for (auto const& worker : workers) {threads_.push_back(std::jthread{ work,worker });}// semaphorethreads_.clear();std::counting_semaphore sp{4};for (int i{ 0 }; i < 20; i++) {threads_.push_back(std::jthread{ [&sp,id = i]() {sp.acquire();std::cout << "thread..."<< id << "\n";std::this_thread::sleep_for(100ms);sp.release();}});}// future and promisestd::promise<int> m_;std::future<int> theFuture{m_.get_future()};std::thread t{ [](std::promise<int> p) { p.set_value(12); }, std::move(m_) };auto va = theFuture.get();std::cout << "the future value:" << va << std::endl;t.join();// 条件变量std::mutex m_mu;std::unique_lock<std::mutex> lock(m_mu);std::condition_variable con_var;std::atomic<int> ca{0};std::async(std::launch::async, [&ca]() {std::cout << "thread the value in: \n";std::this_thread::sleep_for(3s);std::cout << "change the value end: \n";ca = 5;});std::cout << "wait the value: \n";con_var.wait(lock, [&ca]() { return (ca > 0); });std::cout << "wait the value finish:" << ca << std::endl;// packaged_taskstd::packaged_task task{ []() { return 12; } };std::future fur{ task.get_future() };std::thread tt{std::move(task)};auto re = fur.get();std::cout << "wait the task value:" << re << std::endl;tt.join();// shared_futurestd::promise<void> tP1, tP2;std::promise<int> signalP;std::shared_future<int> sf{ signalP.get_future().share() };auto fun1 = [&tP1, sf]() {tP1.set_value();auto p{sf.get()};std::cout << "thread1 get value:" << p << std::endl;};auto fun2 = [&tP2, sf]() {tP2.set_value();auto p{ sf.get() };std::cout << "thread1 get value:" << p << std::endl;};auto res2{ std::async(std::launch::async,fun2) };tP1.get_future().wait();tP2.get_future().wait();signalP.set_value(22);return 1;
}

c++ 多线程编程demo相关推荐

  1. 20180829-Java多线程编程

    Java 多线程编程 Java给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分. 程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 多线程是多任务的一种特 ...

  2. Java多线程编程那些事:volatile解惑--转

    http://www.infoq.com/cn/articles/java-multi-thread-volatile/ 1. 前言 volatile关键字可能是Java开发人员"熟悉而又陌 ...

  3. 多线程编程:阻塞、并发队列的使用总结

    最近,一直在跟设计的任务调度模块周旋,目前终于完成了第一阶段的调试.今天,我想借助博客园平台把最近在设计过程中,使用队列和集合的一些基础知识给大家总结一下,方便大家以后直接copy.本文都是一些没有技 ...

  4. Javascript 多线程编程​的前世今生

    作者:jolamjiang,腾讯 WXG 前端开发工程师 一篇关于 Web Worker.SharedArrayBuffer.Atomics 的文章. 为什么要多线程编程 大家看到文章的标题<J ...

  5. Java多线程编程-(5)-使用Lock对象实现同步以及线程间通信

    前几篇: Java多线程编程-(1)-线程安全和锁Synchronized概念 Java多线程编程-(2)-可重入锁以及Synchronized的其他基本特性 Java多线程编程-(3)-线程本地Th ...

  6. 多线程编程—线程池的实现

    多线程编程-线程池的实现 执行与任务分离的组件- 线程池 https://github.com/wangbojing/threadpool 多线程技术主要解决了处理器单元内多个线程执行的问题,它可以显 ...

  7. Linux开发_多线程编程

    Linux下的多线程使用的库是pthread,是一个遵守POSIX接口的函数库. Linux下多线程编程对函数定义原型有要求,必须是void *函数名(void *参数名),或者void 函数名(vo ...

  8. 多线程的实现与多线程的同步机制-让你轻松掌握多线程编程

    多线程的实现与多线程的同步机制 1. 多线程的实现 1.1 继承Thread类 创建一个类,这个类需要继承Thread类 重写Thread类的run方法(run方法中是业务代码) 实例化此线程类 调用 ...

  9. Java多线程编程(四)——死锁问题

    死锁 什么是死锁? 什么情况下会产生死锁? 生产者与消费者 什么是生产者与消费者? Object类的等待和唤醒方法 生产者-消费者案例(唤醒机制) 基本写法 代码书写技巧与"套路" ...

最新文章

  1. 英语教授一针见血:背熟这500个固定搭配,英语成绩随便上100
  2. H5多媒体(用面向对象的方法控制视频、音频播放、暂停、延时暂停)
  3. python 基础教程:字符串内建函数之大小写的区别
  4. C++字符串类型和数字之间的转换
  5. 修改了/etc/systemd/system.conf以后必须使用daemon-reexec
  6. VC屏幕截图,保存为Bmp文件
  7. vue监听移动设备的返回事件
  8. 《Python Cookbook 3rd》笔记(4.3):使用生成器创建新的迭代模式
  9. java 读取 jar properties_java:如何读取properties文件内容
  10. python json dump_为什么json.dump()没有以\ n结尾? - python
  11. mapxtreme 常用实例
  12. SQLserver常用创建表 添加字段sql
  13. 在线vip全网音乐搜索下载源码
  14. 基于市场情绪平稳度的股指期货日内交易策略
  15. (半)自动批量添加QQ好友
  16. 机器学习sklearn-线性回归
  17. 网站盈利模式分析分类
  18. 0基础入行,新手该如何学习SEM
  19. 二手行业能找回“消失的五年”吗?
  20. 使用ElasticSearch进行可扩展搜索

热门文章

  1. crm软件助力企业实现销售自动化
  2. oracle p6安装,Primavera P6 Professional 19.12 中文   含详细安装配置教程  修复链接...
  3. 【局域网共享问题】0x80004005
  4. APP上线到360步骤
  5. linux装入u盘分区失败,linux下U盘分区表修复解决识别问题
  6. 【论文写作分享】如何进行学术论文写作?为什么会觉得写论文非常难呢?如何寻找论文的创新点?附:实用工具网站分享
  7. PMP之假设日志Assumption Log
  8. 容量可动态扩展的LinkedBlockingQueue
  9. Linux - 关于/opt文件夹的说明
  10. EYOU 文章列表如何调用文章主体