我可以使 C++11 类/对象普遍线程安全吗? [英] Can I make a C++11 class/object universally thread safe?

查看:79
本文介绍了我可以使 C++11 类/对象普遍线程安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已阅读 互斥体实现是否可以互换(独立于线程实现),据我所知,通过使用 C++ 11 互斥体,我可以确保我的类对于所有线程实现都是线程安全的.

Having read Can mutex implementations be interchanged (independently of the thread implementation), it is my understanding that I can ensure that my class is thread safe for all thread implementations, by using C++ 11 mutexes.

我的理解正确吗?我期待是(可能有警告)或否(有原因).

Am I correct in my understanding? I am expecting either yes (perhaps with caveats) or no (with reasons).

  • 我的代码可能需要在目标平台上重新编译,但不需要更改我的源代码.(@彼得)
  • 或者说,我应该能够针对特定平台进行编译并提供可以与任何线程库安全使用的 .so?

鉴于投反对票,我会尽量准确.

Given the down voting, I will try to be more precise.

互斥体的 C++11 实现独立是否与任何其他线程 API 无关?C++11 互斥体是否只知道彼此并独立于执行线程如何到达该点来实现阻塞.

Is the C++11 implementation of mutexes independent of any other thread API? Do C++11 mutexes only know about each other and implement blocking independently of how the thread of execution reached that point.

C++11 互斥锁是否总是与 OpenMP 一起使用(需要重新编译)?团队 A 能否提供一个线程安全的 API(使用 C++ 互斥锁)供团队 B 使用,而不管团队 B 使用的特定线程 API 是什么?所有代码都可以重新编译.

Will a C++11 mutex always work with OpenMP (with recompilation) ? Can Team A deliver a thread safe API (using C++ mutexes) for use by Team B, regardless of the particular thread API used by Team B? All code can be recompiled.

我附上了一个工作示例.

I am attaching a working example.

#include <iostream>
#include <omp.h>
#include <mutex>
class A {
    unsigned n = 0;

public:

    void inc() {
        ++n;
    }

    unsigned get() {
        return n;
    }
};

class B {
    std::mutex mutex;
    unsigned n = 0;

public:

    void inc() {
        mutex.lock();
        ++n;
        mutex.unlock();

    }

    unsigned get() {
        return n;
    }
};

int main() {

    A a;
    B b;
#pragma omp parallel for
    for (int i = 0; i < 100000; i++) {
        a.inc();
        b.inc();
    }

    std::cout << a.get() << " " << b.get() << std::endl;

}

我上次运行的输出是:

98015 100000

这是运气还是设计?

推荐答案

您始终可以使用互斥锁来使类的成员函数进行交互,而不会出现数据竞争.但这还不足以确保一个对象可以从多个线程中使用而不会发生冲突;您需要更广泛的设计.例如,考虑写出向量的内容:

You can always use mutexes to make the member functions of a class interact without data races. But that's not enough to ensure that an object can be used from multiple threads without conflicts; you need a broader design. For example, consider writing out the contents of a vector:

int size = vec.size();
for (int i = 0; i < size; ++i)
    std::cout << vec[i] << ' ';
std::cout << '\n';

使用内部互斥锁,对 vec.size() 的调用和对 vec::operator[] 的调用没有数据竞争,因此它们是安全"以从多个线程调用.但是这段代码有一个问题:如果另一个线程从向量中删除了一个元素,那么向量会比原来小,这个循环会跑到最后.

With an internal mutex, the call to vec.size() and the calls to vec::operator[] do not have data races, so they are "safe" to call from multiple threads. But this code has a problem: if another thread removes an element from the vector then the vector will be smaller than it was, and this loop will run off the end.

这篇关于我可以使 C++11 类/对象普遍线程安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆