繁体   English   中英

如果 object 在另一个线程中使用,是否可以使用对象的属性?

[英]Can object’s property be used, if object used in another thread?

当主线程尝试调用SetX时,下面的示例是否会产生未定义的行为并崩溃,因为虽然x属性没有在新线程中被访问,但object本身是?

class Object{
public:
int x;
int y;

Object(int x, int y)
{
this->x = x;
this->y = y;
}

void SetX(int x)
{
this->x = x;
}

}*object = nullptr;

int *value_only = nullptr;

void ch()
{
    while(true) // assume there is some mechanism to quit loop
    {
         //with obj variable
         //readonly
         auto link = obj;
         auto y = obj->y;

         //write
         obj->y = 5;


         //without obj variable
         //read
         auto yy = *value_only;

         //write
         *value_only = 2;


         // note that obj->x is not touched
    }
}

int main()
{
obj = new Object(1,2);
value_only = &obj->y;

thread th(ch);

obj->SetX(4);

// assume, th termination is handled

return 0;
}

不,访问同一个 object 的两个不同成员没有问题。

请注意,这两个成员都是公共的,setter 除了设置成员之外什么都不做。 因此,您可以重写ch以引用obj->y作为参数并且在 main 中,而不是调用SetX它可以使用int& x = obj->x; . 也许那么更明显的是两个线程实际上并不共享数据。

在线程中,您复制obj但仅复制指针。

但是,您的程序将由于未加入线程而崩溃。 std::thread在其析构函数中未加入(或分离)时调用std::terminate 无论如何,您都会泄漏obj的 memory 。 虽然从main返回时泄漏 memory 并不是什么大问题,但obj可能会管理需要在析构函数中正确关闭的其他资源(文件、数据库连接等)。

我在代码中的评论:

#include <future>
#include <mutex>

class Object
{
public:
    Object(int x, int y) :
        m_x{ x },
        m_y{ y }
    {
    }

    void SetX(int x)
    {
        m_x = x;
    }

    int GetX()
    {
        return m_x;
    }

private:
    int m_x;        
    int m_y;
};

int main()
{
    auto obj_ptr = std::make_shared<Object>(1, 2);

    // capture obj_ptr by value, making a copy of shared_ptr will increase its 
    // reference count. When the lambda finishes the shared_ptr will decrease the reference count.
    auto future = std::async([obj_ptr]
        {
            obj_ptr->SetX(3);
        });

    // destructor of the future will block until async is complete
    // so no race condition at shutdown
    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM