gpt4 book ai didi

multithreading - 具有静态互斥量和线程安全性的静态成员

转载 作者:行者123 更新时间:2023-12-03 13:12:24 24 4
gpt4 key购买 nike

我有一个与此类似的模板类:

template <typename T>
class Foo {
public:
static void show () {
unique_lock<mutex> l {mtx};
for (const auto& v : vec) {
cout << v << endl;
}
}

static void add (T s) {
unique_lock<mutex> l {mtx};
vec.push_back (s);
}

private:
static mutex mtx;
static vector<T> vec;
};

template <typename T> mutex Foo<T>::mtx;
template <typename T> vector<T> Foo<T>::vec;

此类的用法如下所示:
Foo<string>::add ("d");
Foo<string>::add ("dr");
Foo<string>::add ("dre");
Foo<string>::add ("drew");
Foo<string>::show ();

您能告诉我此类是否是线程安全的吗?如果不是,如何制作线程安全版本?

如果我在有一个带有成员函数(非静态)和互斥量(非静态)的类时正确理解了该代码,那么我们可以防止已跨线程传递的单个对象的竞争状态,对吗?并且当我们有类似的东西时,我们防止竞争条件不是针对对象而是针对类,在这种情况下是针对特定类型的,还是我错了?

最佳答案

对我来说看上去很好。直至某一点。
mtx是“保护” vec,以确保在show()期间修改矢量时,不能在add()中进行迭代。

如果这是它的角色,请考虑将其称为vec_mtx

到某一点?
首先,您的使用(实际上)并不表示正在发生任何线程,因此我(非常)不知道您要实现的目标。

例如,如果所有这些添加都发生在一个线程中并在另一个线程中显示,那么您的代码(显然)将不会确保所有都在显示之前进行了
它只会(在逻辑上)确保它发生在所有对象之前,严格地在两个对象之间或在所有对象之后发生。

尽管不适用于您的用例,但如果您保留对传入的字符串对象的引用或将“T”类型与“浅”复制构造函数一起使用,则可能会遇到麻烦。

考虑Foo::add(buffer);并继续修改缓冲区,以便show()在一个线程中执行,而strcat(buffer,.)在另一个线程中执行,并且缓冲区暂时不以'\0'结尾。繁荣!预订前往塞格布勒市的票(那里是草绿色,女孩则很漂亮)。

您需要(非常努力地)看待共享什么数据以及如何共享数据。
几乎所有不合格的语句“X是线程安全的”对于所有X都是假的。
您应该始终(始终)确定它们的安全用途和/或安全范围。
模板的使用时间是10倍。

几乎所有的模板“保证”都可以通过使用某种C数组(或包含指针或在其他地方引用的复杂结构,在将其传递到此处的线程中同时在其上涂抹)的基础上吹掉的。自己不安全!

反复出现一个谬论,即如果您通过某种线程安全的交换结构(例如队列)共享数据,您将获得某种线程安全的保证,而您无需再考虑它,而可以回到单线程的想法。

在这里结束这一课。

注意:从理论上讲,可以在内存匮乏的环境中实现std::string,该环境可以主动地“合并”复制字符串,使您处于甚至没有想到的竞争条件下。您了解的理论。

关于multithreading - 具有静态互斥量和线程安全性的静态成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27780730/

24 4 0