C++ Vector,来自另一个线程的push_back崩溃了?

发布于 2024-10-07 04:37:52 字数 834 浏览 0 评论 0原文

我的代码中使用经过检查的 STL 实现时出现了意外的断言失败。

经过一番研究,我将问题范围缩小到从与创建向量的线程不同的线程调用的向量中的 Push_back。

重现此问题的最简单代码是:

class SomeClass
    {
    private:
        std::vector<int> theVector;
    public:
        SomeClass () 
        {
            theVector.push_back(1); // Ok
        }


        void add()
     {
          theVector.push_back(1); // Crash 
     }
};

唯一的区别是 SomeClass 是从我的主线程实例化的,而 add 是从另一个线程调用的。但是,不存在并发问题:在我用于故障排除的最简单的代码形式中,除了我上面提到的情况之外,没有人从这个向量中读取或写入。

跟踪push_back代码,我注意到std::vector中的一些方法,如count()或size(),当从另一个线程调用时返回垃圾(方法“add”),而当从创建线程调用时返回正确的值(例如在构造函数中)

我应该得出结论 std::vector 在多线程环境中不可用吗?或者这个问题有解决办法吗?

编辑:删除了易失性

编辑2:您认为问题可能不在于多线程吗?在我的测试运行中,add 仅被调用一次(使用断点进行验证)。如果我从构造函数中删除push_back,我仍然会崩溃。因此最终,即使只调用一次向量的方法,在调用一次的函数中也会使断言失败。因此不可能存在并发,或者......?

I have unexpected assertions faillures in my code using a checked STL implentation.

After some research, I narrowed down the problem to a push_back in a vector called from a different thread than the one in which the vector was created.

The simplest code to reproduce this problem is :

class SomeClass
    {
    private:
        std::vector<int> theVector;
    public:
        SomeClass () 
        {
            theVector.push_back(1); // Ok
        }


        void add()
     {
          theVector.push_back(1); // Crash 
     }
};

The only difference is that SomeClass is instanciated from my main thread, and add is called from another thread. However, there is no concurency issue : in the simplest form of code I used for troubleshooting nobody is reading or writing from this vector except the cases I mentioned above.

Tracing into the push_back code, I noticed that some methods from std::vector like count() or size() return garbage, when it's called from the other thred (method "add"), and correct values when called from the creating thread (in the constructor for example)

Should I conclude that std::vector is not usable in a multithreaded environement ? Or is there a solution for this problem ?

EDIT : removed volatile

EDIT 2 : Do you think it's possible that the problem doesn't lie in multithread ? In my test run, add is called only once (verified using a break point). If I remove the push_back from the constructor, I still crashes. So in the end, even with only one call to a vector's method, in a function called once make the assertion fail. Therefore there can't be concurency, or ... ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

固执像三岁 2024-10-14 04:37:52

std::vector 绝对可以在多线程环境中使用,前提是您不能同时从两个线程访问向量。我一直这样做,没有遇到任何麻烦。

由于 vector 不是问题所在,因此您需要更仔细地查看同步机制,因为这很可能是问题所在。

我注意到您将向量标记为易失性。您是否期望使其易失性能够提供同步?因为它不会。 请参阅此处了解更多信息

编辑:最初提供了错误的链接。现在这个问题已经解决了。抱歉造成混乱。

std::vector definitely is usable in a multi-threaded environment, provided you don't access the vector from two threads at once. I do it all the time without trouble.

Since vector isn't the problem, you need to look more closely at your synchronization mechanism, as this is most likely the problem.

I noticed that you marked the vector as volatile. Do you expect that making it volatile will provide synchronization? Because it won't. See here for more information.

EDIT: Originally provided wrong link. This is now fixed. Sorry for confusion.

染火枫林 2024-10-14 04:37:52

如果您可以保证在调用 push_back 时没有人写入或读取向量,那么它就没有理由失败。您可能正在处理更高级别的内存损坏。您应该验证“this”是否指向 SomeClass 的真实实例,检查它的其他成员等。

If you can guarantee that nobody is writing to or reading from the vector when you call push_back, there's no reason that it should fail. You could be dealing with higher-level memory corruption. You should verify that "this" points to a genuine instance of SomeClass, check it's other members, etc.

笑脸一如从前 2024-10-14 04:37:52

大多数 STL 实现都不是线程安全的。您需要使用线程同步(例如互斥锁)来防止两个线程在访问向量时互相干扰。基本上,您需要做的是创建一个包含向量和互斥锁以及访问器函数的类,以保护向量的读写操作。

Most STL implementations are not thread safe. You'll need to use thread synchronization (e.g. mutex) to prevent both threads from stomping on each other while accessing the vector. Basically, what you will need to do is create a class that contains the vector and a mutex and accessor functions that protect the vector for both reading and writing operations.

甜心小果奶 2024-10-14 04:37:52

标准库是否支持多线程是实现定义的。您必须阅读特定编译器的文档。

另外,您可以做的是添加一些日志消息,如以下代码所示:

class SomeClass
    {
    private:
        volatile std::vector<int> theVector;
    public:
        SomeClass () 
        {
            std::cout << "SomeClass::SomeClass" << std::endl;
            theVector.push_back(1); // Ok
        }
        ~SomeClass ()
        {
            std::cout << "SomeClass::~SomeClass" << std::endl;
        }
        void add()
        {
            std::cout << "SomeClass::add" << std::endl;
            theVector.push_back(1);
        }
};

确保当您调用 add 函数时,SomeClass 的实例仍然存在。

Whether Standard Library supports multithreading is implementation defined. You have to read documentation for your specific compiler.

Additionaly what you can do is to add some log messages as in the following code:

class SomeClass
    {
    private:
        volatile std::vector<int> theVector;
    public:
        SomeClass () 
        {
            std::cout << "SomeClass::SomeClass" << std::endl;
            theVector.push_back(1); // Ok
        }
        ~SomeClass ()
        {
            std::cout << "SomeClass::~SomeClass" << std::endl;
        }
        void add()
        {
            std::cout << "SomeClass::add" << std::endl;
            theVector.push_back(1);
        }
};

Make sure that instance of the SomeClass is still exists when you call add function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文