2013-02-25 4 views
1

저는 C++의 초보자이고 C++ 11 스레드로 재생할 때 "분할 오류 (코어 덤프)"를 받았습니다. 내가 쓰던 코드를 수정하여 오류가 발생했습니다. 내가 수정 한 부분은C++ 11 스레드로 세그먼트 화 오류 (코어 덤프)

mutex m; 
auto thread_f=[&](int i) 
{ 
    for(int j=i; j<interval.size(); j+=Threads_Number) 
    { 
     vector<Permutation >::iterator it1=(interval.begin()+j); 
     for(vector<Permutation >::iterator it2=it1; it2!=interval.end(); it2++) 
     { 
      if(!(*it1<*it2)) continue; 
      IntervalToCheck x(*it1,*it2); 
      m.lock(); 
      cout<<x; 
      f<<x; 
      m.unlock(); 
     } 
    } 
}; 

vector<thread> threads; 
threads.clear(); 
for(int i=0; i<Threads_Number; i++) 
    threads.push_back(thread(thread_f,i)); 
for(auto& th:threads) 
    th.join(); 

입니다. 여기서 varient "f"는 ofstream의 객체입니다. 이상하게도 "Threads_Number"를 1로 설정하면 프로그램이 잘 작동하고 1보다 "Threads_Number"를 설정하면 프로그램이 가끔은 잘 작동하지 않는 경우가 있습니다. 예전처럼 int를 초기화하지 않습니다. 그것을 사용하십시오.

g++ -c main.cpp --std=c++11 

g++ *.o -o work -lcln -lginac -pthread 

내 코드를 컴파일하려면 : 내가 사용

[email protected]:multiThreads> g++ --version           13-02-25 14:24 
g++ (GCC) 4.7.2 
Copyright (C) 2012 Free Software Foundation, Inc. 

:

는 그리고 이것은 내 g ++ 버전입니다. 그리고 나의 가난한 영어에 대한 미안.

내가 수업 시간에 GiNaC을 사용하기 때문에 (내가 GiNac을 봤 안전 스레드로) 내가 GDB에서

Program received signal SIGSEGV, Segmentation fault. 
[Switching to Thread 0x7ffff5340700 (LWP 3125)] 
0x00000000004097cf in GiNaC::ptr<GiNaC::basic>::operator= (this=0x7fffec000cd0, other=...) at /usr/include/ginac/ptr.h:88 
88    delete p; 

이 n.m가 제안하는 메시지를 얻었 기 때문에 IntervalToCheck하고, 스레드 안전 아니에요 것으로 보인다. 아마도 GiNaC가 문제 일 것입니다. 누구든지 표현을 처리 할 수있는 열린 도구를 제공 할 수 있다면 좋을 것입니다. 읽으려면 thx.

+3

디버거를 사용하여 충돌 문제를 해결하는 방법에 대해 알아보십시오. 'gdb your-program-name'이 시작해야합니다. –

+2

빈 벡터를 'clear()'하는 것은 의미가 없습니다. 'm.lock()'과'm.unlock()'을 호출해서는 안된다. 대신에 표준 잠금 유형 중 하나를 사용해야한다. –

답변

0

세그먼트 오류가 발생한 소스 코드를 보면 GiNaC가 구현 한 reference counting pointer에서 확인할 수 있습니다. 문제는, 내가 이해하는 바에 따르면, 다른 스레드가 여전히 그것을 사용하는 동안 포인터가 너무 일찍 삭제 될 수 있다는 것입니다. 카운터의 증가 및 감소 연산이 스레드 액세스와 관련하여 원자 적이지 않기 때문입니다. 따라서 정의되지 않은 동작 (따라서 segfault 가능) 인 삭제 된 메모리에 액세스하려고합니다.

실제로이 문제가 과거에 발생했습니다 (and the concern was voiced on their mailing list). 프로젝트 관리자가 의도 한대로

GiNaC is not thread-safe, according to its maintainer.

따라서, 당신은 단순히 하나 개 이상의 스레드에서 GiNaC을 사용할 수 없습니다.

이론적으로 아마도 ginac::ptrstd::shared_ptr과 같은 것으로 대체 할 수 있습니다. 이는 참조 횟수 메커니즘과 관련하여 경쟁 조건이 없음을 보장합니다. 따라서 내부 카운터 유형을 std::atomic<int> 또는 이와 비슷한 것으로 바꾸거나 원자 참조 수가있는 다른 구현을 사용할 수있는 경우 프로그램이 작동 할 가능성이 높습니다.

작성한 실제 코드는 제대로 작동해야합니다. print 문은 순서대로 실행되고 인터리빙 될 수 있지만 중요한 블록에서는 올바르게 잠긴 것처럼 보입니다. 더 많은 관용적 인 RAII-enhanced std::scoped_lock을 C++로 사용하는 것이 좋습니다.

관련 문제