代码之家  ›  专栏  ›  技术社区  ›  Mathias Hölzl

对成员变量的线程安全访问

  •  1
  • Mathias Hölzl  · 技术社区  · 11 年前

    所以我有一个类,它生成了一个以类对象为参数的线程。然后在线程中,我调用一个成员函数。我使用Critical_Sections进行同步。

    那么这个实现是线程安全的吗?因为只有成员是线程安全的,而不是类对象。

        class TestThread : public CThread
        {
        public:
            virtual DWORD Work(void* pData) // Thread function
            {
                while (true)
                {
                    if (Closing())
                    {
                        printf("Closing thread");
                        return 0;
                    }
    
                    Lock();   //EnterCritical
                    threadSafeVar++;
                    UnLock(); //LeaveCritical
    
                }
            }
    
            int GetCounter()
            {
                int tmp;
                Lock();   //EnterCritical
                tmp = threadSafeVar;
                UnLock(); //LeaveCritical
    
                return tmp;
            }
    
        private:
            int threadSafeVar;
        };
    
    .
    .
    .
    
        TestThread thr;
    
        thr.Run();
    
        while (true)
        {
            printf("%d\n",thr.GetCounter());
        }
    
    2 回复  |  直到 11 年前
        1
  •  2
  •   DavidJ    5 年前

    如果该成员是您的关键部分,则只应锁定对其的访问权限。

    顺便说一句,你可以实现类似Locker的功能:

    class Locker
    {
        mutex &m_;
    
     public:
        Locker(mutex &m) : m_(m)
        {
          m.acquire();
        }
        ~Locker()
        {
          m_.release();
        }
    };
    

    您的代码看起来像:

    mutex myVarMutex;
    ...
    {
        Locker lock(myVarMutex);
        threadSafeVar++;
    }
    ...
    int GetCounter()
    {
        Locker lock(myVarMutex);
        return threadSafeVar;
    }
    
        2
  •  1
  •   DavidJ    5 年前

    您的实现是线程安全的,因为您已经用互斥对象保护了对属性的访问。

    在这里,你的类是一个线程,所以你的对象是一个螺纹。这是你在你的线程中所做的,来判断它是否是线程安全的。

    你用一个锁定/解锁系统来获得你的价值,你用同样的系统来写它。所以你的函数是线程安全的。