2012-04-23 78 views
1

为什么根据valgrind使用以下代码会出现竞态条件?tr1 :: randgen()即使使用#pragma omp也存在争用条件critical

#include <iostream> 
#include <ctime> 
#include <tr1/random> 
#include <omp.h> 

using namespace std; 

tr1::mt19937 randgen; 

int random(int min, int max) 
{ 
    int number; 
    if (min!=max) 
    { 
     #pragma omp critical(randgen) 
     number = ((randgen() % (max - min)) + min); 
     return number; 

    } else 
     return min; 
} 

int main(int argc, char *argv[]) 
{ 
    omp_set_num_threads(4); 
    randgen.seed(time(NULL)); 
    #pragma omp parallel for 
    for (int i = 0; i < 10; i++) 
    { 
     random(10,100); 
    } 

    return 0; 
} 

编译为:

g++ -O3 -g -Wall -c -fmessage-length=0 -fopenmp -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.cpp" 
g++ -o "test" ./main.o -lgomp 

Valgrind的结果

valgrind --tool=drd --check-stack-var=yes --read-var-info=yes ./test 
==19561== drd, a thread error detector 
==19561== Copyright (C) 2006-2010, and GNU GPL'd, by Bart Van Assche. 
==19561== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info 
==19561== Command: ./test 
==19561== 
==19561== Thread 3: 
==19561== Conflicting load by thread 3 at 0x00603420 size 4 
==19561== at 0x400A10:  _ZNSt3tr116mersenne_twisterImLi32ELi624ELi397ELi31ELm2567483615ELi11ELi7ELm2636928640ELi15E Lm4022730752ELi18EEclEv.constprop.2 (random.tcc:323) 
==19561== by 0x400BB9: main._omp_fn.0 (main.cpp:16) 
==19561== by 0x4E3FEC9: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0) 
==19561== by 0x4C2A803: vgDrd_thread_wrapper (drd_pthread_intercepts.c:281) 
==19561== by 0x58FDEFB: start_thread (pthread_create.c:304) 
==19561== by 0x543059C: clone (clone.S:112) 
==19561== Location 0x603420 is 0 bytes inside randgen._M_p, 
==19561== a global variable declared at main.cpp:8 
==19561== Other segment start (thread 1) 
==19561== at 0x4C2AE7D: [email protected]* (drd_pthread_intercepts.c:440) 
==19561== by 0x4E402FB: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0) 
==19561== by 0x400898: main (main.cpp:27) 
==19561== Other segment end (thread 1) 
==19561== at 0x4E41550: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0) 
==19561== by 0x4E406CD: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0) 
==19561== by 0x4008A4: main (main.cpp:27) 

我认为,通过使用#pragma OMP关键的只有1个线程在同一时间可以调用特定的函数?我很困惑。

+0

我在这里看不到任何线程问题。 'random','min'和'max'是局部变量,关键指令应该调用'randgen'顺序。 – Tudor 2012-04-23 14:51:32

+0

@Tudor,这就是我困惑的原因。在valgrind中是否存在缺陷? – Mario 2012-04-24 08:54:21

回答

1

您可以找到Valgrind manual答案:

DRD仅支持已配置 这个选项[--disable-Linux的futex的]以及其中符号信息 目前libgomp库。对于大多数Linux发行版,这意味着您将不得不 重新编译GCC。

+0

用--disable-linux-futex重新编译gcc修复了这个问题。唯一的副作用是来自valgrind的一些奇怪消息:chase_cuOff:0x0905e没有条目 chase_cuOff:0x0b661没有条目和更多50个类似条目。任何想法是什么? – Mario 2012-04-27 10:56:25

+0

不知道,对不起。 – user1202136 2012-04-27 11:30:19