数据竞争(data race)是指在非线程安全的情况下,多线程对同一个地址空间进行写操作。一般来说,我们都会通过线程同步方法来保证数据的安全,比如采用互斥量或者读写锁。但是由于某些笔误或者设计的缺陷,还是存在data race的可能性的。(转载请指明出于breaksoftware的csdn博客)

比如下面这段代码

#define _GNU_SOURCE 1#include <pthread.h>
#include <stdio.h>
#include <unistd.h>static pthread_rwlock_t s_rwlock;
static int s_racy;static void sleep_ms(const int ms) {struct timespec delay = { ms / 1000, (ms % 1000) * 1000 * 1000 };nanosleep(&delay, 0);
}static void* thread_func(void* arg) {pthread_rwlock_rdlock(&s_rwlock);s_racy++;pthread_rwlock_unlock(&s_rwlock);sleep_ms(100);return 0;
}int main(int argc, char** argv) {pthread_t thread1;pthread_t thread2;pthread_rwlock_init(&s_rwlock, 0);pthread_create(&thread1, 0, thread_func, 0);pthread_create(&thread2, 0, thread_func, 0);pthread_join(thread1, 0);pthread_join(thread2, 0);pthread_rwlock_destroy(&s_rwlock);fprintf(stderr, "Result: %d\n", s_racy);return 0;
}

线程函数thread_fun主要工作就是对全局变量s_racy进行自增。由于自增是写操作,所以需要加锁。但是第16行加的是读锁——共享锁,这就意味着其他线程也会获得该读锁。这个错误就将导致两个线程同时无协调的修改s_racy变量。

对这个问题,我们可以使用如下指令分析

valgrind --tool=helgrind ./rdlock_race 

最后我们会得到如下的结果显示

==5457== Possible data race during write of size 4 at 0x309078 by thread #3
==5457== Locks held: none
==5457==    at 0x108A19: thread_func (rwlock_race.c:25)
==5457==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==5457==    by 0x4E496DA: start_thread (pthread_create.c:463)
==5457==    by 0x518288E: clone (clone.S:95)
==5457==
==5457== This conflicts with a previous write of size 4 by thread #2
==5457== Locks held: none
==5457==    at 0x108A19: thread_func (rwlock_race.c:25)
==5457==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==5457==    by 0x4E496DA: start_thread (pthread_create.c:463)
==5457==    by 0x518288E: clone (clone.S:95)
==5457==  Address 0x309078 is 0 bytes inside data symbol "s_racy"
==5457== 

第1行显示线程3访问的0x309078地址有4个字节空间可能存在数据竞争。

第2行显示线程3操作这个空间时没有持有独占锁。其具体操作的调用堆栈在第3到第6行体现。

第8行显示线程2也操作了这个空间。

第9行显示线程2操作这个空间是也没有持有独占锁。

第14行则直接指出被操作的空间的变量名称为s_racy。

如此我们便找到存在数据竞争的变量了。

我们将读锁改成写锁——即将pthread_rwlock_rdlock改成pthread_rwlock_wrlock,就不会出现上述分析结果了。

数据竞争(data race)问题分析的利器——valgrind的Helgrind相关推荐

  1. go 并发编程 之 数据竞争 data race (三)

    前言 两个或多个 goroutine 访问同一个资源(如变量或数据结构),并尝试对该资源进行读写而不考虑其他 goroutine.这种类型的代码可以创建你见过的最疯狂和最随机的 bug.通常需要大量的 ...

  2. 数据争用(data race) 和竞态条件(race condition)

    在有关多线程编程的话题中,数据争用(data race) 和竞态条件(race condition)是两个经常被提及的名词,它们两个有着相似的名字,也是我们在并行编程中极力避免出现的.但在处理实际问题 ...

  3. 别混淆数据争用(data race) 和竞态条件(race condition)

    在有关多线程编程的话题中,数据争用(data race) 和竞态条件(race condition)是两个经常被提及的名词,它们两个有着相似的名字,也是我们在并行编程中极力避免出现的.但在处理实际问题 ...

  4. 动态执行流程分析和性能瓶颈分析的利器——valgrind的callgrind

    在<内存.性能问题分析的利器--valgrind>一文中我们简单介绍了下valgrind工具集,本文将使用callgrind工具进行动态执行流程分析和性能瓶颈分析.(转载请指明出于brea ...

  5. 内存问题分析的利器——valgrind的memcheck

    在<内存.性能问题分析的利器--valgrind>一文中我们简单介绍了下valgrind工具集,本文将使用memcheck工具分析各种内存问题.(转载请指明出于breaksoftware的 ...

  6. 死锁问题分析的利器——valgrind的DRD和Helgrind

    在<DllMain中不当操作导致死锁问题的分析--死锁介绍>一文中,我们介绍了死锁产生的原因.一般来说,如果我们对线程同步技术掌握不牢,或者同步方案混乱,极容易导致死锁.本文我们将介绍如何 ...

  7. 互斥量、读写锁长占时分析的利器——valgrind的DRD

    在进行多线程编程时,我们可能会存在同时操作(读.写)同一份内存的可能性.为了保证数据的正确性,我们往往会使用互斥量.读写锁等同步方法.(转载请指明出于breaksoftware的csdn博客) 互斥量 ...

  8. golang data race 竞态条件

    golang race condition 竞态条件 data race race condition golang race detector golang的协程机制使得编写并发代码变得非常容易,但 ...

  9. Go 并发 | 数据竞争及竞争条件

    目录 Go 并发 | 数据竞争及竞争条件 数据竞争 (data race) 避免数据竞争的发生 竞争条件 (race condition) 总结 参考 Go 并发 | 数据竞争及竞争条件 Go 并发中 ...

最新文章

  1. 培训沙龙准备事项-看板记录
  2. 项目管理工具到底应该为谁服务?
  3. MySQL 中 6 个常见的日志问题
  4. mysql讀取sql_SQL 2008连接读取mysql数据的方法
  5. 【年度开源、工具合集】牛津计划,DMTK,Graph Engine…提高你的工作效率!
  6. Python黑客入门:暴力破解zip,零基础也可以学会!
  7. 开源地图引擎openlayers_由quot;地图quot;到quot;指南针quot;:疫后智能营销的演化逻辑...
  8. WINDOWS自带md5校验工具
  9. OpenCL编程入门
  10. 计算机磁盘100,18个方法解决电脑磁盘占用100%
  11. 菜单栏、工具栏、状态栏
  12. 基于Tensorflow实现声纹识别
  13. H5_0021:判断平台和微信
  14. SPSS数据文件读取
  15. 图神经网络 基础与前沿,神经系统知识网络图
  16. linux环境中英文切换配置以及乱码问题
  17. 2019中国机器人大赛窄足机器人赛后总结
  18. 使用CFile类的Write()向.txt文档中写入数据
  19. 简单工厂 工厂方法 抽象工厂
  20. Android安全测试用例(网络资源学习记录)

热门文章

  1. MySQL面试题 | 附答案解析(十三)
  2. Pycharm上传Gitlab
  3. 机器学习中的算法(4.3):SVM----针对线性不可分问题理解
  4. GitHub开源的ImageAI 库:几行代码可实现目标对象识别
  5. 基于pytorch的模型压缩和模型剪枝Model Prune示例
  6. 【深度学习理论】(3) 激活函数
  7. tftp:timeout问题解决 - 从Windows传输文件到开发板
  8. 重装电脑后遇到的问题,其他设备,未知设备
  9. AS3 Socket 基础知识(很全面)
  10. 用Unity和C#创建在线多人游戏学习教程