下面的简单程序偶尔会崩溃,但我不明白它出了什么问题?
它是用“-pthread -std=c++11 -g -O2 -pie -fpie -std=c++11”编译的 valgrind drd 报告数据争用,但我不明白为什么。
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
bool running;
pthread_rwlock_t _rwlock;
class Dummy {
public:
Dummy() : _refs(0) {
Ref();
}
volatile int _refs;
void Ref() {
++_refs;
}
void Unref() {
--_refs;
if (_refs <= 0) {
delete this;
}
}
};
static Dummy* s_dummy;
Dummy* get_dummy() {
pthread_rwlock_rdlock(&_rwlock);
Dummy* ret = s_dummy;
ret->Ref();
pthread_rwlock_unlock(&_rwlock);
return ret;
}
void *work1(void*) {
while (running) {
Dummy* new_dummy = new Dummy();
pthread_rwlock_wrlock(&_rwlock);
Dummy* to_del = s_dummy;
s_dummy = new_dummy;
pthread_rwlock_unlock(&_rwlock);
to_del->Unref();
}
}
void *work2(void*) {
while (running) {
Dummy* p = get_dummy();
p->Unref();
}
}
int main() {
running = true;
pthread_rwlock_init(&_rwlock, NULL);
s_dummy = new Dummy();
pthread_t threads[2];
threads[0] = pthread_create(&threads[0], NULL, work1, NULL);
threads[0] = pthread_create(&threads[1], NULL, work2, NULL);
sleep(30);
running = false;
void* ret;
for (int i = 0; i < 2; ++i) {
pthread_join(threads[i], &ret);
}
return 0;
}
最佳答案
我无法说出您收到的确切消息,因为您没有添加它,但是您至少在 _refs
上发生了数据争用,并且可能会导致双重 删除
。
举个例子,两个线程可以同时位于同一个对象的 Unref
内部,且 _refs 最初 == 2。
假设两个线程都运行 --_refs
,则 _refs
的值将为 0。然后两个线程都会检查 refs
是否为零,并且由于 _refs
是 volatile 的,因此它们都从内存中读取值 0 并删除。
您可能想要的_refs
是一个原子变量,而不是一个 volatile 变量。
关于c++ - 数据竞赛?段错误,但是问题出在哪里呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36111075/