C++ std::vector,线程安全,多线程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9305315/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:38:21  来源:igfitidea点击:

std::vector, thread-safety, multi-threading

c++multithreading

提问by 2607

I am using std::vector as shared data in a multi-threaded application. I encapsulate the thread inside a class, e.g.,

我在多线程应用程序中使用 std::vector 作为共享数据。我将线程封装在一个类中,例如,

class ABC {
public:
    double a, b, c;
};

boost::mutex mutex1;

class XYZ {
public:
    XYZ(vector<ABC> & pVector) {
        ptrVector = &pVector;
        m_thread = boost::thread(&XYZ::Start, this);
    }
    ~XYZ() {}
    void Start();
public:
    vector<ABC> * ptrVector;
    boost::thread m_thread;  
};    

void XYZ::Start() {
    try {
        while(1) {
            boost::this_thread::interruption_point();
            for (unsigned int i=0; i<ptrVector->size(); i++) {
                {
                    boost::mutex::scoped_lock lock(mutex1);
                    ptrVector->at(i).a = double(rand())/10000;  
                    ptrVector->at(i).b = double(rand())/10000;
                    ptrVector->at(i).c = double(rand())/10000;
                }
            }
        }
    }
    catch(boost::thread_interrupted) {}
    catch(std::exception) {} 
}

When I close the application, sometimes, in the debug, there will be 2 error messages, sometimesthere will be no error messages. I often heard people talking about std::vector being not thread-safe, is this one of the cases? I am using Visual Studio 2008, boost thread, the size of the vector is fixed. Can anyone also offer some advice on how to use std::vector in a multi-threaded application.

当我关闭应用程序时,有时,在调试中,会出现 2 条错误消息,有时不会有任何错误消息。我经常听到人们谈论 std::vector 不是线程安全的,这是其中一种情况吗?我使用的是 Visual Studio 2008,boost 线程,向量的大小是固定的。任何人都可以就如何在多线程应用程序中使用 std::vector 提供一些建议。

  1. First-chance exception at 0x7688b9bc in ETP.exe: Microsoft C++ exception: std::out_of_range at memory location 0x02d8f7bc..
  2. First-chance exception at 0x00e916e0 in ETP.exe: 0xC0000005: Access violation reading location 0x00000008.
  3. Second Chance Assertion Failed: File c:\program files (x86)\microsoft visual studio 9.0\vc\include\vector, Line Second Chance Assertion Failed: File c:\program files (x86)\microsoft visual studio 9.0\vc\include\vector98
  1. ETP.exe 中 0x7688b9bc 处的第一次机会异常:Microsoft C++ 异常:std::out_of_range 在内存位置 0x02d8f7bc..
  2. ETP.exe 中 0x00e916e0 处的第一次机会异常:0xC0000005:访问冲突读取位置 0x00000008。
  3. Second Chance Assertion Failed: File c:\program files (x86)\microsoft visual studio 9.0\vc\include\vector, Line Second Chance Assertion Failed: File c:\program files (x86)\microsoft visual studio 9.0\vc\include \vector98

Thanks.

谢谢。

回答by Dietmar Kühl

Actually, it is absolutelypointless to state Xis or is not thread-safe! You need to qualify for what kind of uses. For example, hardly any class will be "thread-safe" when it is somehow used in one thread and destroyed in another.

实际上,声明线程安全或不是线程安全是完全没有意义的X!你需要符合什么样的用途。例如,当某个类以某种方式在一个线程中使用并在另一个线程中销毁时,几乎没有任何类是“线程安全的”。

That said, the statement that std::vector<T>is not thread- safe, independent of how often it is repeated, is wrong. However, it seems most people neither understand nor appreciate the thread-safety guarantees given. std::vector<T>is thread-safe in the following sense:

也就是说,与std::vector<T>重复频率无关的不是线程安全的语句是错误的。然而,似乎大多数人既不理解也不欣赏所提供的线程安全保证。std::vector<T>在以下意义上是线程安全的:

  • You can read a vector object from multiple threads simultaneously.
  • If there is one thread changing a vector object, there shall be neither concurrent readers or writers.
  • Accesses to a vector object don't interfere with other vector objects.
  • 您可以同时从多个线程读取向量对象。
  • 如果有一个线程改变了一个向量对象,则不应有并发的读取者或写入者。
  • 对矢量对象的访问不会干扰其他矢量对象。

This applies to vector structure itself. Accesses to contained object are bound to whatever rules are imposed on them. These are apparently not the thread-safety guarantees many people have in mind but anything stronger won't work with the container interface.

这适用于向量结构本身。对包含对象的访问受强加于它们的任何规则的约束。这些显然不是许多人想到的线程安全保证,但任何更强大的东西都不适用于容器接口。

回答by Clark Gaebel

You call ptrVector->size()without locking it first. This could easily be the cause of your problems. Make sure to lock your vector before any reads or writes.

ptrVector->size()无需先锁定即可调用。这很容易成为您出现问题的原因。确保在任何读取或写入之前锁定您的向量。

回答by screig

Maybe you could use this instead?

也许你可以用这个代替?

concurrent_vector... from the Intel Threading Building Blocks

concurrent_vector... 来自英特尔线程构建模块

https://software.intel.com/en-us/node/467758

https://software.intel.com/en-us/node/467758