2012-02-16 2 views
6

멀티 스레드 응용 프로그램에서 std :: vector를 공유 데이터로 사용하고 있습니다. 나는 때로는 std :: thread 안전성, 멀티 스레딩

class ABC { 
public: 
    double a, b, c; 
}; 

boost::mutex mutex1; 

class XYZ { 
public: 
    XYZ(vector<ABC> & pVector) { 
     ptrVector = &pVector; 
     m_thread = boost::thread(&XYZ::Start, this); 
    } 
    ~XYZ() {} 
    void Start(); 
public: 
    vector<ABC> * ptrVector; 
    boost::thread m_thread; 
};  

void XYZ::Start() { 
    try { 
     while(1) { 
      boost::this_thread::interruption_point(); 
      for (unsigned int i=0; i<ptrVector->size(); i++) { 
       { 
        boost::mutex::scoped_lock lock(mutex1); 
        ptrVector->at(i).a = double(rand())/10000; 
        ptrVector->at(i).b = double(rand())/10000; 
        ptrVector->at(i).c = double(rand())/10000; 
       } 
      } 
     } 
    } 
    catch(boost::thread_interrupted) {} 
    catch(std::exception) {} 
} 

내가 응용 프로그램을 닫습니다

는, 디버그에,이 오류 메시지, 때때로 오류 메시지가 없을 것입니다있을 것, 예를 들어, 클래스 내부의 스레드를 캡슐화합니다. 나는 종종 사람들이 std :: vector에 대해 이야기하는 것을 들었다. thread-safe가 아니라,이 경우 중 하나인가? Visual Studio 2008을 사용하고 있습니다. 스레드를 늘리면 벡터 크기가 고정됩니다. 누구든지 다중 스레드 응용 프로그램에서 std :: vector를 사용하는 방법에 대한 조언을 제공 할 수 있습니까? ETP.exe에서 0x7688b9bc에서

  1. 첫 번째 예외 : 마이크로 소프트 C++ 예외 : 메모리 위치 0x02d8f7bc에서 표준 : : out_of_range .. ETP.exe에서 0x00e916e0에서
  2. 첫 번째 예외 :가 0xc0000005 : 액세스 위반 위치는 0x00000008입니다.
  3. 세컨드 찬스 어설 션 실패 : 파일 C : 9.0 \ VC의 \ 벡터를 \ 포함 마이크로 소프트 비주얼 스튜디오 \ \ 프로그램 파일 (86), 라인 두 번째 기회 어설 션 실패 : 파일 c : 시각 \ 프로그램 파일 (86) \ 마이크로 소프트 스튜디오 9.0 \ vc \ include \ vector98

감사합니다.

+0

벡터는 스레드로부터 안전하지 않습니다. 당신은 그것을 잠그고 있으며 다른 코드를 사용하지 않고 어떻게 사용하고 있는지를 알기 때문에 무엇이 잘못 될지 말할 수 없습니다. 이 특정 코드는 그 자체로 잘 보입니다. – Jarryd

+0

스레드 안전과 별도로 스레드가 벡터에 액세스하는 순서를 고려해야합니다. 한 스레드가 벡터에서 읽는 경우 다른 스레드가 벡터 앞에 쓰여 있는지 확인해야합니다. 코드는 벡터에 기록되지 않은 조건을 처리해야합니다. –

+0

@ Jarryd이 코드에서 뮤텍스를 사용하여 벡터를 잠그는 것 같습니다. 문제가 발생하지 않아야합니다. 자세한 내용은 전체 코드를 참조하십시오. –

답변

22

실제로 무의미한 X은 스레드로부터 안전하지 않거나 안전하지 않습니다! 어떤 용도로 사용할 자격이 필요합니다. 예를 들어, 어떤 클래스도 한 스레드에서 사용되어 다른 스레드에서 파괴되면 "스레드 안전성"이 거의 없습니다.

다시 말해서, std::vector<T>은 스레드가 안전하지 않으며 반복되는 빈도에 관계없이 입니다. 그러나 대부분의 사람들은 주어진 스레드 안전 보장을 이해하거나 감사하지 않습니다. std::vector<T>은 다음과 같은 의미에서 스레드로부터 안전합니다.

  • 여러 스레드에서 동시에 벡터 객체를 읽을 수 있습니다.
  • 벡터 객체를 변경하는 스레드가 하나있는 경우 동시 판독기 또는 작성기가 없어야합니다.
  • 벡터 객체에 대한 액세스가 다른 벡터 객체와 간섭하지 않습니다.

이것은 벡터 구조 자체에 적용됩니다. 포함 된 객체에 대한 액세스는 규칙이 적용되는 모든 것에 바인딩됩니다. 이것들은 분명히 많은 사람들이 염두에두고있는 thread-safety 보장은 아니지만 컨테이너 인터페이스로는 더 강력한 것이 작동하지 않을 것입니다.

+0

조언에 감사드립니다. 이제는 나에게 훨씬 더 분명하다. – 2607

+0

미안하지만, 당신에게 완전히 동의하지 않는다. thread-safe는 구현이 충돌을 피하기 위해 공유 영역을 보호하는 동시 (스레드)를 보장해야한다고 알려진 정의이다. 이것은 클래스가 thread safe한지 아닌지를 의미한다. 사용법에 의존한다는 것은 thread-safe가 아니라는 것을 의미합니다! 이것이 올바른 대답 일 수 있습니까? – Cross

+0

여러 스레드에서 동시에 읽을 수 있습니다. 예 - 마지막 수정 후 메모리 블록이 해제되고 모든 읽기 스레드에서 일치하는 메모리 장벽이 발생하는 한 ... – Persixty

4

ptrVector->size()에 먼저 전화하지 말고 전화하십시오. 이것은 쉽게 귀하의 문제의 원인이 될 수 있습니다. 읽고 쓰기 전에 벡터를 잠급니다.

+1

그는 크기가 벡터는 고정되어 있으므로 문제가 발생하지 않아야합니다. 그러나 더 많은 코드가 없으므로 스레드가 안전하지 않은 방식으로 추가하지는 않습니다. – Jarryd

0

어쩌면 이것을 대신 사용할 수 있을까요?

concurrent_vector ...당신이 다음이 중단됩니다 다른 스레드에서 동시에 쓸하려고하면 인텔 스레딩 빌딩 블록에서

https://software.intel.com/en-us/node/467758