안녕하세요.

Gamecodi 에 질문을 올렸는데 답이 없어서 여기서 답을 얻을 수 있을지 질문 드립니다.

아래 내용을 보시고 혹시 제가 잘못알고 있는 부분이나 잘못된 코드가 있으면 가르침 부탁 드리겠습니다.


Gamecodi 에 올린 질문 링크:

http://lab.gamecodi.com/board/zboard.php?id=GAMECODILAB_QnA_etc&page=1&sn1=&divpage=1&sn=off&ss=on&sc=on&select_arrange=last_comment&desc=desc&no=4552


올린 내용:

Thread 마다 독립된 Map Container 를 사용하려 아래와 같이 하였는데 thread 간에 race condition 이 발생합니다...


사용 방식:

std::vector<Map> g_vec; // std::map 을 element 로 가지고 있는 vector 선언

thread 개수만큼 vector에 비어있는 맵을 미리 할당

0번 thread 는 g_vec[0] 맵만 참조

1번 thread 는 g_vec[1] 만 참조 등등 thread 별로 분리...


구조체 내부에 맵을 선언하고 구조체 배열로 만들어서 사용했을 때는 race condition 문제가 없었는데요. Vector 도 내부적으로 배열이라 알고 있어서 분리된 위치를 참조하기 때문에 race condition 문제가 없을 것으로 봤는데 아닌가 보네요...

이 내용에 대해 알고 계신 분은 설명 좀 부탁 드리겠습니다.


아래는 제가 segment fault 가 발생하는지 확인하려 한 테스트한 코드 입니다.

컴파일 환경 linux gcc, boost 1.50 library 사용


구조체 배열로 확인할 때: g++ -g -O3 -o test vector_of_map_thread.c -lboost_thread -DSTRUCT

vector 로 확인: g++ -g -O3 -o test vector_of_map_thread.c -lboost_thread

OUTPUT 은 vector 에 들어있는 map 들의 size 이며 가끔씩 segment fault 가 발생합니다.



테스트 코드:


#include <boost/thread/thread.hpp>
#include <iostream>
#include <map>
#include <vector>

typedef std::map<int, int> int_map;
#ifdef STRUCT
typedef struct {
    int_map map;
} st;

st g_st[5];
#else
std::vector<int_map> g_vec;
#endif


void map_inserter(const int& no)
{
    for(int i=0; i<10000000; ++i)
    {
#ifdef STRUCT
        int_map &m = g_st[no].map;
#else
        int_map &m = g_vec[no];
#endif
        m.insert(std::pair<int, int>(i,i));
    }
}

int main()
{
    boost::thread_group threads;
    for (int i = 0; i < 5; ++i)
    {
#ifndef STRUCT
        g_vec.push_back(int_map());
#endif
        threads.create_thread(boost::bind(&map_inserter, i));
    }

    threads.join_all();
#ifdef STRUCT
    for(int i=0; i<5; ++i)
        std::cout << g_st[i].map.size() << std::endl;
#else
    std::vector<int_map>::iterator it;
    for(it=g_vec.begin();it!=g_vec.end();++it)
        std::cout << it->size() << std::endl;
#endif
}