2012-10-23 5 views
6

나는 작업을하고있는 백그라운드 스레드를 가지고있다 - 응용 프로그램을로드 중이다. 주 스레드가 UIProgressView에서 진행 상황을 표시하고 있습니다.한 스레드가 다른 스레드가 충돌했는지 어떻게 판단 할 수 있습니까?

몇 차례에

[self performSelectorInBackground:@selector(loadAppInBackground) withObject:self]; 

버그가 발생했습니다 (다른 접근 방식이 문제가 쉽게 해결 할 수있는 경우 그러나, 나는이 방법으로 결혼하고 있지 않다) 배경 스레드는 performSelectorInBackground로 양산되고있다 백그라운드 스레드가 크래시 (앱이 진행되는 다른 버그) 진행 막대가 멈추는 결과를 낳지 만, 사용자는 아무 것도 잘못되었음을 명확하게 알 수 없습니다.

나는이 상황을 감지하고 사용자가 대기 중에 포기할 때까지 매달리기보다는 정상적으로 실패하고 싶습니다.

로드 프로세스의 지속 시간이 크게 다를 수 있으므로 단순히 시간 초과가 이상적인 옵션이 아닙니다.

포 그라운드 스레드가 백그라운드 스레드가 실패했음을 감지하는 가장 좋은 방법은 무엇입니까? 포어 그라운드 스레드는 UI를 다루기에 바쁜 것이므로 첫 번째 스레드를 모니터링하기 위해 두 번째 백그라운드 스레드가 필요합니까? 그것은보기 흉한 것처럼 보입니다.

백그라운드 프로세스를 "ping"하는 데 사용할 수있는 스레드 간 통신 메커니즘이 있습니까? 더 나은 아직, 다른 스레드의 상태를 확인하는 낮은 수준의 시스템 메커니즘?

디버거는 실행중인 모든 스레드를 알고 있으며 상태를 알고있는 것 같습니다. 같은 일을 내 애플 리케이션에 사용할 수있는 전화가 있는지 궁금하네요.

+1

이 백그라운드 작업 (GCD, NSOperations, NSThreads)은 어떻게 디스패치합니까? 대답은 구현에 따라 다릅니다. – CodaFi

+0

[self performSelectorInBackground : @selector (loadAppInBackground) withObject : self]; –

+0

타임 아웃은 주로 사용되는 기술입니다. 스레드가 정상적으로 실행 중인지 아니면 무한 루프에 있는지 (실행 중지 문제)를 판별하는 것이 불가능하기 때문입니다. 따라서 포어 그라운드는 백그라운드 작업이 1 초 (로컬 I/O 또는 네트워크 I/O의 경우 15 ~ 60 초)에 완료되었는지 확인할 수 있습니다. 미안하지만 일반적인 문제를 묻기 때문에 모호한 제안 만 할 수 있습니다. – HKTonyLee

답변

0

백그라운드 스레드의 상태를 직접 확인하는 메커니즘이 목표 C에없는 것처럼 보입니다. 제공되는 응답 중 어느 것이 든 적당한 옵션입니다 ... 시간이 초과되거나 스레드가 계속 존재한다는 증거를 생성하는 경우.

저는 좀 더 간단하고 안정적이며 실시간으로 뭔가를 기대했습니다.

스레드에서 예외를 catch하고 전경 스레드가 수신 대기하고 응답 할 수있는 "BackgroundThreadException"과 같은 알림을 생성하는 실험을 할 것입니다.

1

백그라운드 작업이 일종의 정기적 인주기 (예 : 많은 작업이 이루어지는 큰 루프가 있음)로 실행되는 경우 자주 발생하는 플래그를 설정할 수 있습니다.

이렇게하려면 배경 스레드 저장소를 [NSDate timeIntervalSinceReferenceDate] 어딘가에두고 주 스레드에서 가끔 (타이머를 사용하는 경우) 현재 시간과 비교하십시오. 그 차이가 합당한 한도를 초과하면 배경 스레드가 죽었다고 추측 할 수 있습니다.

또 다른 방법은 백그라운드 스레드가 단순히 부울을 설정하고 주 스레드가이를 조사하고 정기적으로 지우도록하는 것입니다. 부울이 주 스레드 질의 사이에서 다시 설정되지 않으면 죽었다는 것을 추측 할 수 있습니다.

첫 번째 기법은 타이밍이 다소 불규칙한 코드 (어느 스레드에서든)를 허용하는 "합리적인 한계"를 "조정"할 수 있다는 이점이 있습니다. 두 번째 방법은 일반적으로보다 예측 가능한 타이밍을 필요로합니다.

물론 어느 방법을 사용하든 배경 스레드가 방금 끝났을 때 "휘파람을 불고"피하는 방법을 원합니다. 아직 인식하지 못했습니다.

+0

예, 계획 B는 시간 초과를 사용하기 때문에 전체 프로세스를 시간 초과하지 않아도됩니다. 전체로드 프로세스의 각 단계는 개별적으로 시간 초과 될 수 있습니다. 포 그라운드에서 다른 스레드가 여전히 실행 중임을 확인할 수있는 호출이 있었으면합니다. 일부 부작용을 검사하여 임의의 시간 동안 실행 중이 었는지 확인하는 것이 아닙니다. –

+0

@DaveOwens - 문제는 "스레드 죽음"이 너무 자주 잠금 장치에 걸려 있거나 일종의 루프에 걸려 들거나 단순히 실행을 멈추는 것입니다. –

1

일반적인 기술은 해당 스레드의 수명 신호 (소위 하트 비트 스레드)를 검사하는 추가 스레드를 갖는 것입니다. 하트 비트 스레드는 적시에 응답하는지 검사하여 스레드를 폴링하고 그렇지 않은 경우 스레드를 죽은 것으로 간주하고 종료합니다.

간단한 하트 비트 스레드 구현은 다른 스레드가 정기적으로 증가하는 카운터를 확인하는 것입니다. 카운터가 특정 시간 내에 증가하지 않으면 죽은 것으로 간주되어 스레드 다시 시작과 같은 적절한 조치가 취해질 수 있습니다 또는 죽이는 응용 프로그램.또 다른 보편적 인 방법은 hb 쓰레드가 쓰레드로 메시지를 보내고 타임 아웃을 가진 응답을 체크하는 경우이다.

+0

나는 이것이 절대적인 최후의 수단으로 작동 할 것이라고 생각하지만, 알 수없는 속도와 신뢰성의 네트워크를 통해 알려지지 않은 크기의 파일을 다운로드해야하기 때문에 포기하고 백그라운드 스레드가 있다고 가정하기까지 얼마나 많은 시간이 걸릴지 알 수 없습니다. 죽은. –

관련 문제