2014-09-23 2 views
0

이 문제를 잠시 동안 디버깅하려고 시도하고 있으며 무엇을 할 수 있는지 잘 모르겠습니다. 내가하는 일에 능숙하지 않아 논리적 인 오류를 저지르지 마십시오.응용 프로그램이 동시 액세스에서 변수에 충돌하는 중

EXC_BAD_ACCESS 코드 = 1 오류가 발생합니다. 그것은 산발적으로 발생합니다. 충돌이 일어날 때마다 심볼 윈도우는 액세스되는 모든 것이 nil이 아니므로 스레드가 어셈블리로 들어갈 때 데이터가 다른 스레드에 의해 수정되고 충돌을 일으킨다 고 가정합니다. 인터페이스가 원활하게 실행되도록

내가, 내 비디오 출력에 대한 직렬 파견 큐를 시작

- (void) addVideoDataOutput { 
    // (1) Instantiate a new video data output object 
    AVCaptureVideoDataOutput * captureOutput = [[AVCaptureVideoDataOutput alloc] init]; 
    captureOutput.alwaysDiscardsLateVideoFrames = YES; 

    // (2) The sample buffer delegate requires a serial dispatch queue 
    dispatch_queue_t queue; 
    queue = dispatch_queue_create("com.example.tangible.videooutput", DISPATCH_QUEUE_SERIAL); 
    [captureOutput setSampleBufferDelegate:self queue:queue]; 

    // (3) Define the pixel format for the video data output 
    NSString * key = (NSString*)kCVPixelBufferPixelFormatTypeKey; 
    NSNumber * value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; 
    NSDictionary * settings = @{key:value}; 
    [captureOutput setVideoSettings:settings]; 

    // (4) Configure the output port on the captureSession property 
    [self.captureSession addOutput:captureOutput]; 
} 

이 스레드 시작 (그렇지 않으면, 내 게임이 고르지 못함) 카메라가에서 때마다 데이터를 실행 준비된. 이로 인해 "com.example.tangible.videooutput"에서 액세스되는 변수에 대한 잠재적 인 동시 읽기 및 쓰기가 발생합니다. DISPATCH_QUEUE_SERIAL을 사용하고 있으므로 모든 것이 한 번에 하나씩 실행됩니다. 대기열 외부에있는 다른 스레드가 이러한 변수를 편집하고 있다는 뜻입니까? (내 코드에서 발생하지 않는다고 생각합니다)

여러 스레드가 동시에 (직렬 디스패치 대기열을 사용하기 때문에 발생하지 않아야하는) 일부 변수에 액세스한다는 가정하에, 스레드에 의해 액세스되는 변수를 원자 및 복사로 변경했습니다. 이것은 충돌을 멈추게하지 않았다.

나는 모든 작업을 호출하기 전에 각 목록의 전체 복사본 (이들은 동시에 액세스되는 연결된 목록)을 작성해야한다고 생각하는 단계에 있으며,이 작업은 낭비적이고 불필요한.

직렬 디스패치 대기열을 사용함에 따라 이러한 변수가 동시에 액세스되는 이유를 알 수 없으며 해당 대기열의 스레드 외부에있는 모든 것이 이러한 연결 목록에 액세스한다고 생각하지 않습니다.

여기가 충돌 할 때가있는 (때로는) 그림과 변수가 있습니다.

* thread #6: tid = 0x8ed94, 0x0000000191b641dc libobjc.A.dylib`objc_msgSend + 28, queue = 'com.example.tangible.videooutput' 
    frame #0: 0x0000000191b641dc libobjc.A.dylib`objc_msgSend + 28 
    * frame #1: 0x00000001000f5508 Tangible`-[ControlScene removeBlocks](self=0x000000015450cc60, _cmd=0x0000000100556388) + 2096 at ControlScene.mm:342 
    frame #2: 0x00000001000f5764 Tangible`-[ControlScene updateBlocks:](self=0x000000015450cc60, _cmd=0x00000001005559fe, b=0x000000017045a580) + 276 at ControlScene.mm:362 
    frame #3: 0x00000001000e7e08 Tangible`-[StageViewController frameReady:](self=0x0000000154612f70, _cmd=0x0000000100555a0c, frame=<unavailable>) + 640 at StageViewController.mm:94 
    frame #4: 0x00000001000ebbb0 Tangible`-[VideoSource captureOutput:didOutputSampleBuffer:fromConnection:](self=0x0000000170261e80, _cmd=0x0000000183fe21c9, captureOutput=0x0000000170223840, sampleBuffer=0x00000001586091e0, connection=0x0000000170610080) + 340 at VideoSource.mm:131 
    frame #5: 0x0000000183f683c4 AVFoundation`__74-[AVCaptureVideoDataOutput _AVCaptureVideoDataOutput_VideoDataBecameReady]_block_invoke + 412 
    frame #6: 0x000000019212c014 libdispatch.dylib`_dispatch_call_block_and_release + 24 
    frame #7: 0x000000019212bfd4 libdispatch.dylib`_dispatch_client_callout + 16 
    frame #8: 0x00000001921324a8 libdispatch.dylib`_dispatch_queue_drain + 640 
    frame #9: 0x000000019212e4c0 libdispatch.dylib`_dispatch_queue_invoke + 68 
    frame #10: 0x00000001921330f4 libdispatch.dylib`_dispatch_root_queue_drain + 104 
    frame #11: 0x00000001921334fc libdispatch.dylib`_dispatch_worker_thread2 + 76 
    frame #12: 0x00000001922c16bc libsystem_pthread.dylib`_pthread_wqthread + 356 

하십시오 조언 : 여기 enter image description here

는 역 추적입니다. 나는 무슨 일이 벌어지고 있는지 이해하지 못하고 꽤 오랫동안이 버그를 가지고 있습니다. 요청시 다른 코드 스 니펫을 기꺼이 제공합니다.

+0

충돌 정보를 더 많이 공유 할 수 있습니까? (어느 스레드가 항상 같은 위치에 있습니까? 전체 스택 추적을 공유하십시오.) 비디오 처리 스레드가 수행중인 작업과 동일한 모델로 수행중인 기본 스레드 (또는 다른 스레드)에 대해 더 많은 정보를 공유 할 수 있습니까?쓰레드 안전성을 얻기 위해'atomic'과'copy'를 사용하는 것은 조금 걱정 스럽지만 (일반적으로 당신은 돌연변이 구조에 대해 어떤 형태의 잠금이나 동기화 큐를 사용할 것입니다), 나는 더 많은 정보없이 그 결론에 뛰어들 것을 주저합니다. – Rob

+0

전체 스택 추적이 무슨 뜻인지 잘 모르겠습니다. 이것으로 충분합니까? http://i.imgur.com/6SLtBVw.png – joegreen0628

+0

비디오 처리 스레드가 아닌 다른 스레드가 동일한 모델에 대해 아무 것도하지 않는다고 생각합니다. 스택 트레이스에서 볼 수 있듯이, 쓰레드 3만이 나를 작성한 코드를 포함하고있다. 또는 스택 추적을 잘못 읽었습니까? – joegreen0628

답변

0

함수가 호출 될 때마다 새로운 디스패치 대기열을 만들었습니다. queue = dispatch_queue_create ("com.example.tangible.videooutput", DISPATCH_QUEUE_SERIAL);

그래서 동기화하지 못할 수 있습니다. 대기열을 한 번만 만들려고 했습니까?

+1

SO에 오신 것을 환영합니다. 설명을 요청하고 자세한 내용을 보려면 의견을 사용하십시오. –

+0

방금 ​​큐를 인스턴스 변수로 만든 다음 실행하려고했습니다. 문제가 발생했습니다. 잘못된 포인터 액세스. – joegreen0628

0

문제는 동시 액세스가 아니므로 변수를 원자화하거나 잠금을 설정하는 것이 상황을 돕지 못했습니다.

변경 가능한 배열 내에 목록을 링크했지만 이러한 변경 가능한 배열은 강하다고 선언되지 않았습니다. 각 연결된 목록 노드가 가리키고있는 객체도 마찬가지입니다. 따라서 해당 속성을 강하게 변경하면 모든 충돌이 사라졌습니다. =)

관련 문제