使用ThreadSanitizer线程检查工具

ThreadSantizier又叫TSan,是一个检测线程Data Race的C/C++工具,它集成在新版GCC和CLANG中,通过编译时加-fsanitize=thread,可以在运行时检测出Data Race的问题

ThreadSanitizer官网:https://code.google.com/p/thread-sanitizer
Data Race

Data Race是指多个线程在没有正确加锁的情况下,同时访问同一块数据,并且至少有一个线程是写操作,对数据的读取和修改产生了竞争,从而导致各种不可预计的问题。

Data Race的问题非常难查,Data Race一旦发生,结果是不可预期的,也许直接就Crash了,也许导致执行流程错乱了,也许把内存破坏导致之后某个时刻突然Crash了。
环境要求

Linux x86_64,内核版本不要太旧。(经测试,公司旧的开发机Linux内核是2.6.16是跑不了的,新的tlinux内核3.10.0可以)
gcc 4.8版本以上(clang也集成了,3.2版本以上)

官方示例

#include <pthread.h>
#include <stdio.h>
 
int Global;
 
void *Thread1(void *x) {
  Global++;
  return NULL;
}
 
void *Thread2(void *x) {
  Global--;
  return NULL;
}
 
int main() {
  pthread_t t[2];
  pthread_create(&t[0], NULL, Thread1, NULL);
  pthread_create(&t[1], NULL, Thread2, NULL);
  pthread_join(t[0], NULL);
  pthread_join(t[1], NULL);
}

上面的代码在不加锁的情况下,两个线程同时去修改Global变量,从而导致Data Race。使用gcc的-fsanitize=thread 编译,执行
$ g++ simple_race.cc -fsanitize=thread -fPIE -pie -g
$./a.out

WARNING: ThreadSanitizer: data race (pid=26327)
Write of size 4 at 0x7f89554701d0 by thread T1:
#0 Thread1(void*) simple_race.cc:8 (exe+0x000000006e66)

Previous write of size 4 at 0x7f89554701d0 by thread T2:
#0 Thread2(void*) simple_race.cc:13 (exe+0x000000006ed6)

Thread T1 (tid=26328, running) created at:
#0 pthread_create tsan_interceptors.cc:683 (exe+0x00000001108b)
#1 main simple_race.cc:19 (exe+0x000000006f39)

Thread T2 (tid=26329, running) created at:
#0 pthread_create tsan_interceptors.cc:683 (exe+0x00000001108b)

#1 main simple_race.cc:20 (exe+0x000000006f63)

ThreadSanitizer: reported 1 warnings

执行程序,如果发生Data Race,错误信息会直接输出出来。如果错误信息比较多,重定向输出流到文件里,慢慢分析:

$ ./a.out >result.txt 2>&1

关键要点
除了加-fsanitize=thread外,一定要加-fPIE -pie。
-g 是为了能显示文件名和行号。
如果分生成obj(-c)和link两个步骤,每一步都加:thread -fPIE -pie -g,并且在link的时候加-ltsan
只支持64位,最好指定编译64位(-m64)
如果依赖其他静态库,其他静态库编译时必须指定-fPIC(如果不是请重编)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Hutool 是一个Java工具包,其中包含了许多方便实用的工具类,包括线程工具类。下面我们将使用300字回答如何使用Hutool线程工具。 Hutool提供了一些方便的方法来处理线程线程池。首先,我们可以使用`ThreadUtil.sleep()`方法使当前线程休眠指定的时间,以便控制线程的执行时间。 另外,Hutool还提供了一些线程工具类,如`ThreadFactoryBuilder`、`ExecutorBuilder`和`ScheduledExecutorBuilder`,使我们可以方便地创建线程池。 通过`ThreadFactoryBuilder`,我们可以自定义线程名称、线程优先级和线程组等信息来构建线程工厂。 通过`ExecutorBuilder`,我们可以创建自定义的线程池,可以设置核心线程数、最大线程数和线程存活时间等参数,以及自定义线程拒绝策略。 通过`ScheduledExecutorBuilder`,我们可以方便地创建定时执行任务的线程池,可以指定初始延迟时间和周期执行时间等参数。 使用Hutool线程工具,我们还可以方便地实现多线程的集合操作。例如,使用`ThreadUtil.execAsync()`方法可以创建多个线程并发执行,通过`ThreadUtil.join()`方法可以等待所有线程执行完毕。 此外,Hutool还提供了`Watcher`工具类,可以用于监控线程的状态和执行结果。 在使用Hutool线程工具时,我们需要先引入相关的依赖,然后根据需求选择合适的方法和工具类来处理线程线程池操作。 总之,Hutool线程工具提供了许多方便实用的方法和工具类,可以帮助我们更轻松地处理线程线程池的相关操作,提高开发效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值