ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – 用户定义对象的多线程使用

2019-07-26 06:05:58  阅读:216  来源: 互联网

标签:c stl thread-safety


我对使用多个线程的对象有疑问.

首先,使用std :: lock_guard或其他方式保护对象不会同时访问是没有问题的.

下一步是使用volatile声明对象.

class A
{
   public: int val;
};

volatile A a;

但这样做最终会导致很多新函数的类型限定符不稳定
    …
    int GetVal()volatile;
    void SetVal()volatile;
    …

好的,这一切都很好.

但是如何访问stl成员,例如std :: vector或std :: map.

如果我想要一个volatile std :: vector< int>我运行了很多错误,而stl没有定义任何volatile方法.

从这一点开始,我在网上搜索了很多“技巧”.在后台主要有相同的想法:拥有一个用于并发保护的互斥锁,并使用const_cast移动volatile以使标准接口可用.

作为此实现的示例:

template <typename T>
class PseudoPtr {
    public:
        PseudoPtr(volatile T& obj, mutex& mtx) 
            : guard(mtx), 
              pObj_(const_cast<T*>(&obj)) 
        { }   
        ~PseudoPtr() { }   
        // Pointer behaviour
        T& operator*()  {   return *pObj_;  }   
        T* operator->() {   return  pObj_;  }   

    private:
        my_guard<mutex> guard;
        T* pObj_;
        PseudoPtr(const PseudoPtr&) = delete;
        PseudoPtr& operator=(PseudoPtr &) = delete;
};

从上面得到我的示例类没有volatile限定符:

 class A
 {
     ...
     int GetVal();
 };

但是,如果我以下列方式使用它:

 volatile A a;
 mutex mu;

 ...
 for (;;) 
 {
     PseudoPtr ptr(a, mu); //starts locking the object
     if (ptr->GetVal())
     {
         ... do something ...
     }
 }

我永远不会在对象a中看到任何变化,因为编译器可以进行优化
访问,因为volatile对象是const_cast,所以优化器没有
了解挥发性行为.

对于我自己的所有类,这不是问题,而我可以编写所有volatile方法.但是如果我想使用stl容器,就没有办法从它们那里获得volatile实例并通过const_cast使用它.

好的,实际的编译器并不是那么难以优化(gcc 4.6.1),但有保证编译器永远不会进行这种优化吗? const_cast将破坏volatile并且不会对volatile stl对象进行const_cast,因为stl容器根本没有volatile方法.

我认为,网上发现的所有“技巧”都是错误的,因为它们都忽略了
优化.

这在我的问题中运行:

>我对volatile和优化器的解释错了吗?
>对于使用stl conatiner线程安全,是否有“标准”工作解决方案?

———————-经过几个小时的阅读———————- –

首先,是的,pthread_mutex_lock应该执行以下操作:*访问内存原子(这是我之前唯一知道的事情)*保证内存对所有其他线程可见

好的,第二个对我来说是新的!这导致了下一个问题:这个技巧如何运作?

提供互斥语义的库必须有机会告诉编译器,停止乱序执行*将所有缓存(寄存器优化)变量写入硬件*告诉硬件同步所有硬件缓存等.

好的!但是它是如何工作的:特定于gcc的实现:存在一个名为barrier()的宏,就像这样

asm volatile(“”:::“memory”);

gcc的pthread库包含在glibc / nptl中,每个保证数据可见性到其他线程的函数只需调用barrier宏或直接调用内联汇编程序或用类似的东西做事.

如果再没有误会,这就是幕后的简单事情.

我学到的东西:与互斥锁相结合的volatile在任何情况下都没有意义.

我写下这个答案,希望其他人能够在那个神秘面前变得更加沉闷.

如果再次出现错误和误解?!:让我知道!

谢谢你的所有答案!

(很抱歉编辑我的帖子来添加我自己的结论,但我无法在帖子中添加自己的答案)

解决方法:

如果您正在使用互斥锁等来同步对对象的访问,请执行you don’t need volatile at all.

标签:c,stl,thread-safety
来源: https://codeday.me/bug/20190726/1541356.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有