c++ - 数据竞赛?段错误,但是问题出在哪里呢?

标签 c++ multithreading crash

下面的简单程序偶尔会崩溃,但我不明白它出了什么问题?

它是用“-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/

相关文章:

c++ - 如何从基本类继承函数

C++ 使用任意数量的变量调用函数指针

c++ - yaml-cpp 的主要性能问题

c++ - 在 OpenMP 中使用共享数据结构而不是私有(private)数据结构时的性能差异

android - 混淆后,Android应用程序崩溃,也混淆了调试版本中收到的日志

c++ - 找不到头文件错误

multithreading - spark-submit : Difference between “--master local[n]” and “--master local --executor-cores m”

服务与 Activity 不同的Android静态变量

android - Android应用程式当机。将JSON数据放入Listview

ios - 取消向后滑动时,SwiftUI 应用程序卡住,100% CPU