2010-01-13 1 views
2

나는 오디오 데이터를 대기열에 넣기 위해 사용하는 std :: deque에 대한 래퍼를 가지고있다. (중요하다면 libavcodec을 통해 블럭으로 들어온다.)std :: deque의 끝에 블럭 추가하기

void lock()  { SDL_mutexP(mute_access_);  } 
void unlock()  { SDL_mutexV(mute_access_);  } 

내 문제는 data_buffer_ :

16 비트 데이터의 버퍼를 취하고 양단 잠금/잠금 해제의

void AVAudioBuffer::enqueue(int16_t* src, size_t num, double pts) { 
    // Save current size of buffer 
    size_t size = data_buffer_.size(); 

    lock(); 
    data_buffer_.insert(data_buffer_.end(), src, src+num); 
    unlock(); 

// Push PTS value onto queue 
if (pts != AV_NOPTS_VALUE) { 
    pts_values_.push_back(pair<int,double>(size, pts)); 
    } 
} 

정의에 추가 기능이다 .insert 문이 코드에 포함되어 있으면이 함수가있는 스레드가 한 번 실행되고 잠길 수 있습니다. 코드를 제거하면 작동합니다. 삽입을 src 데이터의 수동 반복으로 바꾸고 각 요소에 대해 push_back()을 호출하여 스레드를 잠급니다.

이것은 양키에 데이터를 추가하는 유효한 방법입니까? 테스트 프로그램에서 시도해 보았지만 제대로 작동하는 것 같았습니다. 설명서에 문제가 없다는 것을 암시하는 것으로 보입니다. 왜 내 스레드가 죽을까요?

업데이트 정보 : 잠금/잠금 해제가 실패 할 때 추가 된 오류 메시지가 모두 잘 처리됩니다. 나는 그들이 쌍으로 처형 당하고 있는지 확인하기 위해 그들을 설치했다. 그것은 deque :: insert 호출로 뭔가를 엉망으로 만들고, 제거 할 수 있고, 다시 움직이기 시작합니다.

업데이트 : 나는 문제가, 내가 코드를 리팩토링과 상수는 그래서 디큐는 항상 루프 = (일부 스레드 잠금이 필요한 것처럼

+0

"스레드가 잠기 게합니까?"라는 것은 무엇을 의미합니까? 디버거에서 보면, "잠긴"(콜 스택)은 어디입니까? –

+0

죄송합니다. lock()/unlock() 함수는 SDL 뮤텍스를 둘러싼 래퍼입니다. 해당 정의로 게시물을 업데이트하겠습니다. –

+0

deque 부분과 잠금/잠금 해제 기능을 포함하여 더 많거나 적은 코드를 게시 할 수 있습니까? 게시 된 코드에 크기 및 pts 변수를 사용하지 않으므로 검색으로 이어질 수있는 중요한 내용이 표시되지 않을 가능성이 높습니다. –

답변

0

소리가 발생, 전체로 확인되었다 놓친 발견 다른 스레드가 읽기됩니다. 큐에서 (따라서 갱신은) 다음은

아차 고정 돼 - 잠금이가 내 생각은 잠금 장치가 작동하지 않거나 것을 독자가

잠금되지 독자 스레드 잠금 장치를 않는다는 것입니다. 자물쇠가 실제로 잠그고 있습니까?

1

deque에 삽입하는 방법이 완벽하게 유효합니다.

잠금 장치의 원인은 잠금 자체에 있습니다. data_buffer_에 대한 모든 액세스는 data_buffer_.size()에 대한 호출을 포함하여 동기화되어야합니다 (읽기 및 쓰기 모두). 한 스레드가 data_buffer_에서 읽는 동안 다른 스레드가 스레드에 쓰면 임의의 정의되지 않은 동작을 얻을 수 있습니다.

고정 된 후에도 여전히 잠겨 있습니다. 일치하지 않는 lock()/unlock() 쌍 또는 교착 상태가 있는지 확인하십시오. 나는 또한 당신이 원자 잠금 장치를 사용하고 있다고 가정합니다.

업데이트 된 코드를 보면 pts_values_에 대한 액세스를 동기화해야합니다.

+0

그게 내가 궁금한 점이다. 전화가 안좋을 때가 아니라면, 어디서 멈추고 있는지 알아 내야 할 것이다. –

1

그림과 같이 STL 사용이 문제가 없으므로 동기화를 면밀히 관찰하는 것이 좋습니다. SDL 뮤텍스 함수는 오류시 -1을 반환합니다. 예를 들어, lock()unlock()에 해당 사항을 확인하고 예외를 발생시킵니다. 항목에 대한 스레드 ID를 해당 기능에 너무 로깅 할 수 있습니다.

또한 입력 값이 올바른지 확인합니다. num은 입력 버퍼를 오버런하지 않습니다.

좋은 C++ 기술을위한 플러그 - 잠금 관리를 위해 RAII을 사용하는 습관을 갖습니다.이것은 C++ 소멸자가 발명 된 것입니다.

+0

둘 중 하나의 상태가 -1이고 잠금 및 잠금 해제가 모두 정상적으로 작동하는 경우 오류 메시지가 추가되었습니다. –