2013-06-26 4 views
1

취업 면접에서이 질문을 받았으며 저의 삶에서 대답을 찾을 수 없었습니다. (서면 시험이므로 답변을 드릴 수 없습니다) 어떻게하는 것이 가능하다 -하지만 때로는 thread2 않습니다 인쇄 그의 모든 메시지를하면서 (마지막 메시지를 인쇄하지 않음) 존재하지 thread1 -교착 상태를 찾을 수 없습니다

int thread2_finished = 0; 

void t1() { 
    printf("t1 is running\n"); 
    while (!thread2_finished) { usleep(50); } 
    printf("t2 is doing stuff\n");  
} 


void t2() { 
    printf("t2 is running\n"); 
    sleep(5); 
    printf("t2 woke up\n");  
    thread2_finished = 1; 
    printf("t2 finished\n"); 
} 

우리가 알고있는 것은 그것이 작동하는 시간의 대부분이다?

저는 여기에 기본적인 것이 빠졌지 만 캐시에 문제가 있다는 것을 생각할 수있는 유일한 방법은 T1이 값 (0)을로드하고 캐시 한 다음 즉시 T2가 값을 변경한다는 것입니다 1,하지만 몇 가지 이상한 이유로 T1은 오래된 캐시 된 값을 계속 사용하지만 그것은 나에게 이상한 것 같습니다.

+0

그리고 질문은 무엇입니까? – carlito

+0

질문은 (또한 편집 된 게시물) - thread1이 어떤 종류의 교착 상태에있는 동안 thread2가 어떻게 완료 될 수 있습니까? –

+1

'휘발성'? 't1()'은't2()'가'thread2_finished'의 값을 변경했다는 사실을 알지 못할 수도 있습니다. 이것은 두 개의 스레드가 다른 CPU 코어에서 실행 중일 때 발생할 수 있습니다. – Kane

답변

1

코드는 옳은 것처럼 보이지만 (로직 방식입니다) 실제 환경을 사용하면 제대로 작동하지 않을 수 있습니다. 휘도가이지만 그 이유는 다소 복잡합니다. 이 키워드의 동작이 모든 언어/컴파일러를 변경하기 때문에 여기에 올바른 단어가 표시됩니다. answer

1

t2가 실행될 때 t1이 시작되었다고 보장 할 수는 없습니다. sleep은 적절한 스레드 동기화를 대체 할 수 없습니다.

또한 thread2_finished은 휘발성이어야한다고 주장 할 수도 있습니다. 실제로는 컴파일러가 usleep이 무엇을하는지 알지 못하므로 실제로는 중요하지 않습니다. 따라서 usleep이 전역 변수를 변경하지 않는다고 가정 할 수 없습니다. 반면에, 많은 아키텍처에서 전역 변수를 업데이트하는 것보다 더 나은 동기화가 필요합니다. 일부 스레드에서는 (다른 CPU에서 실행중인 경우) 오랜 시간 동안 전역 변수의 업데이트 된 값을 볼 수 없으며, 캐시에 일관성이없는 경우 다른 스레드에서 볼 수 없을 수도 있습니다. 운영 체제의 잠금 프리미티브는 한 스레드의 부작용을 다른 스레드가 볼 수 있도록 충분한 논리를 제공해야합니다.

간단히 말해서, 대부분의 경우 작동 할 수 있지만 그렇게하지 마십시오. 적절한 잠금, 조건 변수 및 세마포어를 사용하십시오.

관련 문제