【问题标题】:C++ Vectors / Classes /ThreadingC++ 向量/类/线程
【发布时间】:2011-01-01 20:03:50
【问题描述】:

我正在使用 Win7 / VS2008 (9) SDK 6/7.1

我在使用的代码中遇到问题
mini版代码如下

class CONNECTION
{
    int/std::string/bool vars; // just to make it simple
    CONNECTION ( int defaultvar );
    CONNECTION ( const CONNECTION& copycon )
    ~CONNECTION ( );
    DWORD static WINAPI staticstart( void *param )  //HACK to use createthread on classes
    { return ((CONNECTION *)param)->main); } // yea it works fine
    DWORD main();
};

这个类没有带有副本和析构函数的默认构造函数 所有变量都被很好地复制并且析构函数不会留下任何内存泄漏,构造函数很简单,就像将参数分配给变量一样。所有变量和代码都被省略以使其简单,因为它们不是问题。

class main
{
    std::vector<CONNECTION> con;
    int addcon( int defaultvarofcon )
    {
        CONNECTION temp( defaultvar );
        con.push_back( temp );
        return con.size() - 1;
    }
}

到目前为止一切顺利 当我运行一个只有包含和此代码的控制台测试程序时

main mymainclass;
mymainclass.addcon( 0 );

程序运行良好关闭没有错误
但是当我添加像

这样的额外代码时
main mymainclass;
mymainclass.addcon( 0 );
mymainclass.addcon( 1 );
mymainclass.addcon( 2 );

程序因访问冲突而崩溃 在检查了我的代码两次后,我在所有线程上逐步调试它,我发现只有当我在向量中使用一个元素时,主线程才能读取主线程和工作线程中所有向量类/元素的正确值

但是,如果我使用多个像第二个代码一样的代码,则它们自己线程上所有元素的所有数据都无法访问(错误指针)。但在主线程上,它们仍然正确并显示正确的值

谁能帮我弄清楚这段代码有什么问题?

【问题讨论】:

  • 作为任何仅供参考,因为你的类有一个复制构造函数和一个析构函数,它应该几乎肯定有一个赋值运算符。目前尚不清楚这是否与您的问题有关,但这肯定是一个等待发生的错误。
  • 不,不是。也许它可能会发生,但现在不是问题:/

标签: c++ multithreading class vector


【解决方案1】:

std::vector 并非设计为线程安全的。因此,您必须使用某种互斥锁来确保一次只有一个线程访问它。

否则,如果任何线程调整向量的大小,向量可能必须分配新的存储空间,复制元素,然后释放旧的存储空间......显然在其他线程正在使用旧存储空间时释放旧存储空间是一件非常糟糕的事情.

您需要自己分配CONNECTION 对象。让std::vector 管理它们意味着当向量调整大小时它们将在内存中移动,并且其他线程持有的指针悬空。调整向量的大小会使指向其任何内容的所有指针无效。

【讨论】:

  • 我已经检查过了。没有变量被跨线程访问。线程之间也不共享变量
  • 我忘了,除此之外我不是在谈论共享变量。如果你看到上面的代码,你会看到我在谈论实例的变量。它不被任何其他线程共享或访问。
  • @VirusEcks:等等,你是不是在创建新线程?看起来您将指向CONNECTION 实例的指针传递给staticstart,但是内存被释放(当std::vector 调整大小时),所以当staticstart 尝试通过该指针调用实例方法时,您的程序崩溃。
  • @ben Voigt:调整矢量大小时内存被释放?我不知道。但 。在主线程中我可以看到正确的数据。所以内存没有被释放
  • @VIrusEcks:在主线程中,您会看到正确的数据,因为在释放旧内存之前,内容已复制到新地址。但是现在它是一个新地址...您在其他线程中使用的所有指针仍然保留旧地址,不再存在。
【解决方案2】:

如果需要自定义析构函数和复制构造函数,probably 还需要自定义赋值运算符。

否则,您很快就会得到几个类实例引用相同的内部指针/...,很容易导致内存损坏和访问冲突。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    • 2016-08-14
    • 1970-01-01
    • 1970-01-01
    • 2012-08-28
    相关资源
    最近更新 更多