shared_ptr 객체를 멀티스레드에서 사용할 때 의문점

ByteBuffer 클래스를 만들고 매소드 get, size 선언. private 맴버를 d, s를 두어 아래와같이 구현하였다.

#include <algorithm>

ByteBuffer::ByteBuffer(char *data, int size)
{
    if(size == 0)
    {
        d = nullptr;
        s = 0;
    }
    else if(data == nullptr)
    {
        d = new char[size];
        s = size;
    }
    else
    {
        d = new char[size];
        s = size;

        std::copy(data, data + size, d);
    }
}

ByteBuffer::~ByteBuffer()
{
    delete[] d;
}

char *ByteBuffer::get()
{
    return d;
}

int ByteBuffer::size()
{
    return s;
}

그리고 두개의 스레드에서 위 객체를 사용하는데… 몇시간 돌리다보면 자꾸 엑세스 오류가 발생하고 디버거 연결하여 실행하면 항상 저 객체에서 이미 free 된 메모리가 free된다고 브레이크 걸리거나 포인터가 NULL이여서 엑세스 오류가 발생했다. (객체를 생성할 때 size나 data나 값이 0이면 애초 객체를 생성하지 않도록하여 ByteBuffer::get()을 호출하면 0이 반환 될 일이 없다.)

참조카운트는 스레드 안전하다는데 그렇지않은 현상. 객체가 생성되고 콜백하는 코드는 아래와같았다.

callback(opaque, std::shared_ptr<ByteBuffer>(new ByteBuffer((char *)data, size)));

표준안에서는 shared_ptr의 객체 참조는 스레드 안전하다고는 되어있고… 실제 돌려보면 그렇지않고… 일단 구글링해보면 나오는 예제들은 아래와같은 형식을 띄고있었다.

std::shared_ptr<ByteBuffer> sharedData(new ByteBuffer((char *)data, size));

callback(opaque, sharedData);

당최 MSVC에서의 C++11은 제대로 구현되지않은것이 몇몇 있다고들었기에 그냥 MSVC의 stl로 위 형식으로 고치는 삽질은 패스하고 곧장 오래 전부터 shared_ptr이 구현되어있던 믿을만한 boost로 갈아타서 돌려보는 중.

boost::shared_ptr<ByteBuffer> sharedData(new ByteBuffer((char *)data, size));

callback(opaque, sharedData);

지금은 저렇게 고쳐서 돌려보고있는데… 만약 그래도 객체참조가 문제생기면 mutex를 쓰던 좀 더 삽질을 해봐야겠다.

P.S.  한시간 넘게 돌려보니 마찬가지 문제 발생. 로직을 다시 봐야겠다.

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다

*
*

This site uses Akismet to reduce spam. Learn how your comment data is processed.