代码之家  ›  专栏  ›  技术社区  ›  Ali Sepehri-Amin

使用原子而不是CriticalSection?

  •  2
  • Ali Sepehri-Amin  · 技术社区  · 8 年前

    我有一个代码,可以提供一些数据,对文件进行一些操作等等。 我使用1个线程提供数据,4个线程读取和搜索数据内部。

    这4个线程使用文件向量进行搜索(使用相同的函数)。为了避免同步问题(所有线程在同一时间读取相同的文件),我使用 CriticalSection() WinAPI:

    void ReadData(char* fileName)
    {
       EnterCriticalSection(&CriticalSection);
    
       // Open file
    
       // Read file data
       std::vector<std::string> data;
    
       ... Find data inside file
    
       // Close file
    
       LeaveCriticalSection(&CriticalSection);
    }
    

    但我看到了这个 Post 这是:

    std::atomic 而不是CriticalSection?或者我不理解原子的用法。

    2 回复  |  直到 8 年前
        1
  •  3
  •   Community Mohan Dere    5 年前

    使用标准C++

    在代码中,您使用 EnterCriticalSection() LeaveCriticalSection() 微软WinAPI的功能。

    这些都有wto的主要不便:第一,它们不可移植,第二,它们不安全:如果一个例外会导致线程离开,会发生什么 ReadData() 以一种意想不到的方式?您可能会得到一个关键部分,在windows看来,该部分不会被留下,从而耗尽所有其他线程!

    lock_guard mutex ,如所示 Werner ,更安全:首先,它可以跨平台移植,但此外,它实现了 RAII 习惯用法,确保在出现意外异常时 lock_护罩 当函数保留时被破坏,导致 互斥体 待发布。

    使用原子可能还不够

    通常,人们倾向于使用原子,因为原子避免了数据竞争,给人的印象是它将解决所有线程同步问题。

    其他替代方案

    Parallel Pattern Library .

    另一方面,如果您只使用向量来存储文件的行并按顺序处理它们,那么您也可以考虑使用队列,其优点是能够使用许多可用的线程安全实现之一,例如 boost .

        2
  •  3
  •   Werner Erasmus    8 年前

    std::atomic 对于向量不重载。它也不可复制或移动( from here here ),因此不能将其用作std::vector value_类型(或者可能需要提供自己的专门化,我没有(也不会)尝试/ed)。

    但是,如果您希望代码独立于平台, std::mutex 会做得很好,例如:

    std::mutex myMutex_; //Typically a member or static or in unnamed namespace
    
    void ReadData(char* fileName)
    {
       std::lock_guard<std::mutex> guard(myMutex_);
       // Open file
    
       // Read file data
       std::vector<std::string> data;
    
       ... Find data inside file
    
       // Close file
    
       //... Releases when scoped left...
    }
    

    this previous post .