一、数据竞争的产生

在下面例子中:

void function_1()
{
for (int i = ; i < ; i++)
{
std::cout << "from function 1:" << i << std::endl;
} } int main()
{
std::thread t(function_1); for (int i = ; i < ; i++)
{
std::cout << "from function main:"<<i<<std::endl;
} t.join(); std::getchar(); return ;
}

我们发现其输出的毫无规律,因为主线程和子线程同时调用cout对象造成的,产生了数据竞争

二、互斥对象

上面的问题可以通过互斥对象来解决

#include "stdafx.h"
#include <iostream>
#include <thread>
#include <mutex>
#include <string>
using namespace std;
std::mutex mu; void share_print(std::string msg,int id)
{
mu.lock();
cout << msg << id << endl;
mu.unlock();
} void function_1()
{
for (int i = ; i < ; i++)
{
share_print("from function 1:",i);
} } int main()
{
std::thread t(function_1); for (int i = ; i < ; i++)
{
share_print("from main:", i);
} t.join(); std::getchar(); return ;
}

但是如果cout中发现异常,那么程序将被永远锁住,除非能够保证要锁住的对象不会出现问题,有此引出一下方法

void share_print(std::string msg,int id)
{
std::lock_guard<std::mutex> gard(mu);
cout << msg << id << endl; }

此类并不能阻止其他线程调用cout

三、LogfFile类

 class LogfFile
{
public:
LogfFile() {
f.open("log.txt");
}
void share_print(std::string msg, int id)
{
std::lock_guard<std::mutex> gard(m_mutex);
f << msg << id << endl; } private:
std::mutex m_mutex;
std::ofstream f;
}; void function_1(LogfFile & log)
{
for (int i = ; i < ; i++)
{
log.share_print("from function 1:",i);
} } int main()
{
LogfFile log;
std::thread t(function_1,ref(log)); for (int i = ; i < ; i++)
{
log.share_print("from main:", i);
} t.join(); std::getchar(); return ;
}

注意f不能对外开放

 多线程一----多线程的应用

多线程二----简单线程管理

多线程三----数据竞争和互斥对象

多线程四----死锁和防止死锁

多线程五----unick_lock和once_flag

多线程六----条件变量

多线程七----线程间通信

c++11の数据竞争和互斥对象的更多相关文章

  1. c++多线程の数据竞争和互斥对象

    看两个代码: void function() { ;i>;i--) { cout<<"from sub thread"+i<<endl; } } vo ...

  2. 2016年11月3日JS脚本简介数据类型: 1.整型:int 2.小数类型: float(单精度) double(双精度) decimal () 3.字符类型: chr 4.字符串类型:sting 5.日期时间:datetime 6.布尔型数据:bool 7.对象类型:object 8.二进制:binary 语言类型: 1.强类型语言:c++ c c# java 2.弱类型语

    数据类型: 1.整型:int 2.小数类型: float(单精度) double(双精度) decimal () 3.字符类型: chr 4.字符串类型:sting 5.日期时间:datetime 6 ...

  3. Java 多线程 死锁 隐性死锁 数据竞争 恶性数据竞争 错误解决深入分析 全方向举例

    在几乎所有编程语言中,由于多线程引发的错误都有着难以再现的特点,程序的死锁或其它多线程错误可能只在某些特殊的情形下才出现,或在不同的VM上运行同一个程序时错误表现不同.因此,在编写多线程程序时,事先认 ...

  4. c++多线程编程之互斥对象(锁)的使用之----死锁

    一.死锁会在什么情况发生 1.假设有如下代码 mutex;   //代表一个全局互斥对象 void  A() { mutex.lock(); //这里操作共享数据 B();  //这里调用B方法 mu ...

  5. EF+LINQ事物处理 C# 使用NLog记录日志入门操作 ASP.NET MVC多语言 仿微软网站效果(转) 详解C#特性和反射(一) c# API接受图片文件以Base64格式上传图片 .NET读取json数据并绑定到对象

    EF+LINQ事物处理   在使用EF的情况下,怎么进行事务的处理,来减少数据操作时的失误,比如重复插入数据等等这些问题,这都是经常会遇到的一些问题 但是如果是我有多个站点,然后存在同类型的角色去操作 ...

  6. 速战速决 (6) - PHP: 获取 http 请求数据, 获取 get 数据 和 post 数据, json 字符串与对象之间的相互转换

    [源码下载] 速战速决 (6) - PHP: 获取 http 请求数据, 获取 get 数据 和 post 数据, json 字符串与对象之间的相互转换 作者:webabcd 介绍速战速决 之 PHP ...

  7. 互斥对象 Mutex 和MFC中的CMutex

    互斥(Mutex)是一种用途非常广泛的内核对象.能够保证多个线程对同一共享资源的互斥访问.同临界区有些类似,只有拥有互斥对象的线程才具有访问资源的权限,由于互斥对象只有一个,因此就决定了任何情况下此共 ...

  8. C++11之使用或禁用对象的默认函数

    [C++11之使用或禁用对象的默认函数] C++11 允许显式地表明采用或拒用编译器提供的内置函数.例如要求类型带有默认构造函数,可以用以下的语法: 另一方面,也可以禁止编译器自动产生某些函数.如下面 ...

  9. QTableWidget 用法总结(只能使用标准的数据模型,并且其单元格数据是QTableWidgetItem的对象)

    QTableWidget是QT程序中常用的显示数据表格的空间,很类似于VC.C#中的DataGrid.说到QTableWidget,就必须讲一下它跟QTabelView的区别了.QTableWidge ...

随机推荐

  1. 使用Redmine的PHP API时,如何判断需求是否为原子需求

    使用Redmine的PHP API时,如何判断需求是否为原子需求 使用redmine的PHP接口时,怎样才能判断需求是否为原子需求呢,下面给出具体的做法: /** * 判断是否为原子需求, 即是否依然 ...

  2. DocX开源WORD操作组件的学习系列四

    DocX学习系列 DocX开源WORD操作组件的学习系列一 : http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_sharp_001_docx1.htm ...

  3. 二进制安装部署kubernetes集群---超详细教程

    本文收录在容器技术学习系列文章总目录 前言:本篇博客是博主踩过无数坑,反复查阅资料,一步步搭建完成后整理的个人心得,分享给大家~~~ 本文所需的安装包,都上传在我的网盘中,需要的可以打赏博主一杯咖啡钱 ...

  4. MEF 基础简介 一

    前言 小编菜鸟级别的程序员最近感慨颇多,经历了三五春秋深知程序路途遥远而我沧海一粟看不到的尽头到不了的终点何处是我停留的驿站.说了段废话下面进入正题吧! 什么是MEF? MEF:全称Managed E ...

  5. Unity的四元素与Vector3的乘积的含义

    Quaternion.Euler(x,y,z)含义是按照每个旋转轴以x,y,z旋转度旋转,例子:Quaternion.Euler(45,45,45) Quaternion与Vector3的右乘操作(* ...

  6. 【微服务No.2】polly微服务故障处理库

    熔断.降级: 熔断:熔断就是我们常说的“保险丝”,意为当服务出现某些状况时,切断服务,从而防止应用程序不断地常识执行可能会失败的操作造成系统的“雪崩”,或者大量的超时等待导致系统卡死等情况,很多地方也 ...

  7. JS截取数字

    Math是javascript的一个内部对象,该对象的方法主要是一些数学计算方法floor:下退 Math.floor(12.9999) = 12ceil:上进 Math.ceil(12.1) = 1 ...

  8. 【查漏补缺】File的path、absolutePath和canonicalPath的区别

    背景 在学习Idea的插件开发时,用到了相关的VirtualFileSystem这个东西,里面的VirtualFile有一个getCanonicalPath()方法引起了我的注意,我发现我不知道-- ...

  9. 3 Redis 的常用五大数据类型

    2016-12-21 14:54:20 该系列文章链接NoSQL 数据库简介Redis的安装及及一些杂项基础知识Redis 的常用五大数据类型(key,string,hash,list,set,zse ...

  10. Windows中通过命令行新建文件夹、新建文件,和一些常用命令

    新建文件 和Linux不太一样,Linux中的touch和vi命令创建新文件的方法都不能用了,在windows命令行下得用type nul>文件名.后缀名来创建: F:\study\vue\wo ...