线程安全使用std :: map

时间:2015-01-26 02:51:56

标签: c++ multithreading visual-studio-2008 stl

我有一个std::map<int, object*>我需要从不同的线程访问(读写)。当然,我可以只使用一个关键部分进行读写,但它会对性能产生巨大影响,因为我有很多find()次调用(每秒几千)并且写入次数少得多(通常,创建和销毁线程时一次插入和一次擦除。)

因此,我需要使用CriticalSection进行写入,并且只在检查之前检查另一个线程是否正在执行写操作。但是怎么样? 我找到了C ++ 11和boost的解决方案,但我使用的是Visual Studio 2008(因为兼容性问题)。

有人可以给我一个例子或解释如何做吗?谢谢!

2 个答案:

答案 0 :(得分:0)

您可以创建一个包装std :: map的类,并使用互斥锁将写/读函数锁定。使用互斥结构作为此类的成员,并根据功能锁定/解锁。

Windows API有一些mutex functions来注册系统的互斥锁句柄。句柄用作Windows识别互斥锁并检查它是否在等待的方式。

这是一个简单的互斥类,可以帮助您开始使用某些Windows API调用。

class MyMutex {

    private:
        HANDLE m_hMutex; 

    public:
        MyMutex()
        {
            m_hMutex = CreateMutex(NULL, FALSE, NULL);
        }

        ~MyMutex()
        {
            CloseHandle(m_hMutex);
        }

        void Lock()
        {
            BOOL test = WaitForSingleObject( m_hMutex, INFINITE );
        }

        void UnLock() 
        {
            ReleaseMutex( m_hMutex );
        }
};

答案 1 :(得分:0)

您正在寻找的是多读者/单作家锁定系统。不幸的是,没有内置类型(在C ++ 14之前)。如果你可以使用提升,那么你可以使用提升shared_mutex

如果没有,你必须自己做(在SO上阅读other thread)。您也可以在T.C.的评论中使用MS SRW锁定(请参阅there)。

现在,假设您的班级shared_mutex已明确定义且可用。您只需将一个shared_mutex对象作为属性添加到要保护的类中。我建议你在你的类中保持完全无锁的方法,并在它们周围添加包装器,如下所示:

class Whatever;
class MyClass {
    boost::shared_mutex mutex;
    Whatever find_unlocked() {
        whatever blob_blob;
        blob_blob = do_whatever_work_find_does();
        return blob_blob;
    }
    void write_smth_unlocked() {
        do_something_that_needs_writing_to_MyClass();
    }
public:
    Whatever find() {
        Whatever blob;
        mutex.lock_shared(); // Locks for reading (shared ownership on the mutex)
        blob = find_unlocked();
        mutex.unlock_shared();
        return blob;
    }
    void write_smth() {
        mutex.lock(); // Locks for writing (exclusive ownership on the mutex)
        write_smth_unlocked();
        mutex.unlock();
    }
};

这样做将使您能够重用在类的新功能中定义的操作,同时仍然能够通过锁定系统保护整个新操作。

最后,您可以使用两种方法来定义任何操作:

  • 私有(或受保护)方法:operation_unlocked()
  • 公开的一个:operation(),它使用shared_mutex