线程同步是指同一进程中的多个线程互相协调工作从而达到一致性。之所以需要线程同步,是因为多个线程同时对一个数据对象进行修改操作时,可能会对数据造成破坏,下面是多个线程同时修改同一数据造成破坏的例子:

 1 #include <thread>
 2 #include <iostream>
 3
 4 void Fun_1(unsigned int &counter);
 5 void Fun_2(unsigned int &counter);
 6
 7 int main()
 8 {
 9     unsigned int counter = 0;
10     std::thread thrd_1(Fun_1, counter);
11     std::thread thrd_2(Fun_2, counter);
12     thrd_1.join();
13     thrd_2.join();
14     system("pause");
15     return 0;
16 }
17
18 void Fun_1(unsigned int &counter)
19 {
20     while (true)
21     {
22         ++counter;
23         if (counter < 1000)
24         {
25             std::cout << "Function 1 counting " << counter << "...\n";
26         }
27         else
28         {
29             break;
30         }
31     }
32 }
33
34 void Fun_2(unsigned int &counter)
35 {
36     while (true)
37     {
38         ++counter;
39         if (counter < 1000)
40         {
41             std::cout << "Function 2 counting " << counter << "...\n";
42         }
43         else
44         {
45             break;
46         }
47     }
48 }

运行结果如图所示:

显然输出的结果存在问题,变量并没有按顺序递增,所以线程同步是很重要的。在这里记录三种线程同步的方式:

  ①使用C++标准库的thread、mutex头文件:

 1 #include <thread>
 2 #include <mutex>
 3 #include <iostream>
 4
 5 void Fun_1();
 6 void Fun_2();
 7
 8 unsigned int counter = 0;
 9 std::mutex mtx;
10
11 int main()
12 {
13     std::thread thrd_1(Fun_1);
14     std::thread thrd_2(Fun_2);
15     thrd_1.join();
16     thrd_2.join();
17     system("pause");
18     return 0;
19 }
20
21 void Fun_1()
22 {
23     while (true)
24     {
25         std::lock_guard<std::mutex> mtx_locker(mtx);
26         ++counter;
27         if (counter < 1000)
28         {
29             std::cout << "Function 1 counting " << counter << "...\n";
30         }
31         else
32         {
33             break;
34         }
35     }
36 }
37
38 void Fun_2()
39 {
40     while (true)
41     {
42         std::lock_guard<std::mutex> mtx_locker(mtx);
43         ++counter;
44         if (counter < 1000)
45         {
46             std::cout << "Function 2 counting " << counter << "...\n";
47         }
48         else
49         {
50             break;
51         }
52     }
53 }

  这段代码与前面一段代码唯一的区别就是在两个线程关联的函数中加了一句 std::lock_guard<std::mutex> mtx_locker(mtx); 在C++中,通过构造std::mutex的实例来创建互斥元,可通过调用其成员函数lock()和unlock()来实现加锁和解锁,然后这是不推荐的做法,因为这要求程序员在离开函数的每条代码路径上都调用unlock(),包括由于异常所导致的在内。作为替代,标准库提供了std::lock_guard类模板,实现了互斥元的RAII惯用语法(资源获取即初始化)。该对象在构造时锁定所给的互斥元,析构时解锁该互斥元,从而保证被锁定的互斥元始终被正确解锁。代码运行结果如下图所示,可见得到了正确的结果。

c++实现多线程同步相关推荐

  1. python多线程读取文件的问题_Python多线程同步---文件读写控制方法

    1.实现文件读写的文件ltz_schedule_times.py #! /usr/bin/env python #coding=utf-8 import os def ReadTimes(): res ...

  2. 【转】windows平台多线程同步之Mutex的应用

    线程组成: 线程的内核对象,操作系统用来管理该线程的数据结构. 线程堆栈,它用于维护线程在执行代码时需要的所有参数和局部变量.   操作系统为每一个运行线程安排一定的CPU时间 -- 时间片.系统通过 ...

  3. java线程条件变量_多线程同步条件变量(转载)

    最近看<UNIX环境高级编程>多线程同步,看到他举例说条件变量pthread_cond_t怎么用,愣是没有看懂,只好在网上找了份代码,跑了跑,才弄明白 #include #include ...

  4. MFC多线程同步互斥

    MFC多线程同步互斥[转载] http://blog.sina.com.cn/s/blog_62d15fb601017dhn.html https://www.cnblogs.com/zhanghu5 ...

  5. 34 多线程同步之Event

    事件用于线程之间的通信.一个线程发出一个信号,其他一个或多个线程等待,调用Event对象的wait方法,线程则会阻塞等待,直到别的线程set之后才会被唤醒. [示例 1]使用Event实现多线程同步 ...

  6. 线程同步锁 java_java多线程同步之重入锁,详细解析

    上次已经为大家介绍过java多线程同步,Volatile详解的主要内容了.今天再来为大家介绍一些相关的内容,也就是java多线程同步之重入锁,一起来了解一下吧. 使用重入锁实现线程同步 在JavaSE ...

  7. Servlet基础(三) Servlet的多线程同步问题

    Servlet基础(三) Servlet的多线程同步问题 Servlet/JSP技术和ASP.PHP等相比,由于其多线程运行而具有很高的执行效率. 由于Servlet/JSP默认是以多线程模式执行的, ...

  8. windows多线程同步--临界区

    推荐参考博客:秒杀多线程第五篇 经典线程同步 关键段CS 关于临界区的观念,一般操作系统书上面都有. 适用范围:它只能同步一个进程中的线程,不能跨进程同步.一般用它来做单个进程内的代码快同步,效率比较 ...

  9. 使用NSCondition实现多线程同步

    iOS中实现多线程技术有非常多方法. 这里说说使用NSCondition实现多线程同步的问题,也就是解决生产者消费者问题(如收发同步等等). 问题流程例如以下: 消费者取得锁,取产品,假设没有,则wa ...

  10. javaweb:servlet的多线程同步问题

    1. Servlet/JSP技术和ASP,PHP等相比,由于其多线程运行而具有很高的执行效率. 2. 由于Servlet/JSP默认是以多线程模式执行的,所以,在编写代码时需要非常细致地考虑多线程的同 ...

最新文章

  1. jQuery元素操作
  2. Hadoop安装之JDK在Centos虚拟机中安装
  3. Docker入门-安装
  4. 判断给定的两个数是否是亲和数_动画演示LeetCode算法题:004-寻找两个有序数组的中位数...
  5. 项目经理必须知道什么是PERT网络分析(计划评审技术)
  6. clover更新驱动 后不能开机_Big Sur安装常见问题【持续更新】
  7. 龙芯3a5000下编译postgresql 14.3
  8. 工业控制计算机固态硬盘,工业级固态硬盘的标准有哪几类
  9. 爬取相关机构电话号码及地址
  10. iGrimaceV8 V8在线威锋源apt.so/qwkjv8手机直接下载安装教程图:
  11. 控制led亮度C语言程序,单片机pwm控制led亮度原理图
  12. aps是什么意思_aps画幅是什么意思
  13. 深入JUnit源码之Runner
  14. 【ML特征工程】第 5 章 :分类变量:机器鸡时代的鸡蛋计数
  15. 全志平台WiFi无法连接AP问题调试(1)问题分析
  16. Web安全之《SSH暴力破解》
  17. 生成SSH Key(linux)
  18. Jensen–Shannon divergence
  19. MySQL 的 20+ 条最佳实践
  20. centos7建站操作步骤

热门文章

  1. 利用Vulnhub复现漏洞 - Atlassian Confluence 路径穿越与命令执行漏洞(CVE-2019-3396)
  2. android仿头条广告,Android仿今日头条手界面
  3. HttpWebRequest(未授权设置) 即需要身份验证设置
  4. Java中输入一个学员的成绩,输出四种结果:优秀,良好,及格,不及格
  5. 中国做生意的方法彻底变了!你再弄不懂就无钱可赚!
  6. 曼昆《经济学原理》第一二章部分
  7. iOS动画之CAAnimationGroup
  8. shell181网格划分_ANSYS中Shell181单元介绍谁知道
  9. Scratch编程与科学结合-磁铁
  10. 末日要塞找不到服务器,末日要塞攻略 末日要塞流程攻略