数据竞争(data race)问题分析的利器——valgrind的Helgrind
? ? ? ? 數據競爭(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的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 死锁问题分析的利器——valgrind的
- 下一篇: 从0开始搭建编程框架——思考