2014-03-13 1 views
2

here에 따르면 pthread_spin_lock을 사용하여 스레드가 블룸의 스케줄러에 의해 인터럽트 될 수 있고 해당 자원에 포함 된 다른 스레드가 회전 할 수 있으므로 중요한 섹션을 잠그는 것은 위험합니다 .선점, pthread_spin_lock 및 기본 제공

pthread_spin_lock에서 atomic 내장 + compare_and_swap idion을 통해 구현 된 잠금으로 전환한다고 가정 해 봅시다.이 문제가 개선 되더라도 여전히 문제가 있습니까?

pthread으로 인해 선점을 해제하는 데 아무런 문제가없는 것 같습니다. 원자력을 통해 구현 된 잠금을 사용하거나 내가 볼 수있는 것을 사용하는 경우에 할 수있는 일이 있습니까?

작은 임계 영역 잠금에 관심이 있습니다.

+0

'pthread_spin_lock'은 아마 원자 연산으로 구현됩니다. 무엇을 달성하기를 원합니 까? 만약 당신이 * 중요한 * 내부에서 * 수행하고자하는 것들이 단지 업데이트/증분이거나 그와 같은 것들이라면, 당신은 확실하게 작업을 수행하기 위해 atomic buildins (또는 C11'_Atomic')을 사용해야하고 전혀 잠그지 않아야합니다. –

+0

중요한 섹션을 pthread_spin_lock으로 잠 그려고합니다. 삽입 된 URL에 따르면 다른 스레드가 무기한으로 회전 할 위험이 있다고 보입니다. 내 질문은 compare_and_swap + atomic을 사용하여 중요한 영역의 lokcing을 구현하면 어떻게됩니까? 선점 때문에 무한대로 스핀 할 위험이있는 다른 스레드가 있습니까? –

+0

@Jens : 좀 더 설명해 드리겠습니다. 나는 작은 중요한 섹션을 잠글 필요가있다. –

답변

3

pthread_mutex_lock에는 일반적으로 잠금을 획득하기 위해 원자 적 조작을 사용하는 빠른 경로가 있습니다. 자물쇠가 소유되지 않은 경우, 이것은 매우 빠를 수 있습니다. 잠금이 이미 유지 된 경우에만 스레드가 시스템 호출을 통해 커널에 들어갑니다. 커널은 스핀 락을 획득하고 뮤텍스가 처음 시도 된 이후에 릴리스 될 경우 뮤텍스를 획득하기 위해 다시 시도합니다. 이 시도가 실패하면 호출 스레드가 mutex와 연관된 대기 대기열에 추가되고 컨텍스트 전환이 수행됩니다. 커널은 뮤텍스에 비트를 설정하여 대기중인 스레드가 있음을 나타냅니다.

pthread_mutex_unlock에도 빠른 경로가 있습니다. 대기 스레드 플래그가 클리어되면 잠금을 해제 할 수 있습니다. 플래그가 설정되면 스레드는 시스템 호출을 통해 커널에 들어가야 대기 스레드를 깨울 수 있습니다. 다시 말하지만, 커널은 스레드 제어 데이터 구조를 조작 할 수 있도록 스핀 잠금을 획득해야합니다. 결국 대기중인 스레드가없는 경우 커널에서 잠금을 해제 할 수 있습니다. 대기중인 스레드가 있으면 실행 가능하게 만들어 뮤텍스의 소유권을 해제하지 않고 전송합니다.

이 작은 춤에는 많은 미묘한 경쟁 조건이 있으며 잘하면 모든 것이 올바르게 작동합니다.

잠긴 뮤텍스를 획득하려고 시도하는 스레드는 컨텍스트 전환되므로 해당 스레드가 뮤텍스를 소유하지 못하게하지 않으므로 소유자에게 중요한 섹션을 종료하고 뮤텍스를 릴리스 할 수 있습니다.

반면에 잠긴 스핀 록을 획득하려고 시도하는 스레드는 단순히 회전하여 CPU주기를 소모합니다. 이것은 스핀 록을 소유 한 스레드가 임계 영역을 벗어나서 잠금을 해제하지 못하게 할 가능성이 있습니다. 회전하는 스레드는 타임 슬라이스가 소비되었을 때 선점 될 수 있으므로 잠금을 소유 한 스레드는 결국 제어권을 다시 얻을 수 있습니다. 물론 이것은 성능면에서는 좋지 않습니다.

실제로 스핀 잠금은 스레드가 잠금을 소유하는 동안 선점 될 가능성이없는 경우에 사용됩니다. 커널은 CPU 당 플래그를 설정하여 인터럽트 서비스 루틴에서 컨텍스트 전환을 수행하지 못하게 할 수 있습니다 (또는 컨텍스트 전환을 유발할 수있는 인터럽트를 방지하기 위해 인터럽트 우선 순위 수준을 높이거나 인터럽트를 모두 비활성화 할 수 있음). 사용자 스레드는 자신의 우선 순위를 높임으로써 (동일한 프로세스의 다른 스레드에 의해) 선점되는 것을 방지 할 수 있습니다. 단일 프로세서 시스템에서 현재 스레드가 선점되지 않도록 방지하면 스핀 잠금 장치가 필요하지 않습니다. 또는 다중 프로세서 시스템에서 서로 선점 할 수 없도록 스레드를 cpus (CPU 친 화성)에 바인드 할 수 있습니다.

모든 잠금에는 궁극적으로 원자 기본 요소가 필요합니다 (물론 효율적인 잠금, 카운터 예제에는 here 참조).뮤텍스는 논쟁이 심각 할 때 비효율적 일 수있어 스레드가 커널에 지속적으로 들어가고 컨텍스트가 전환 될 수 있습니다. 특히 임계 영역이 커널 오버 헤드보다 작 으면 더욱 그렇습니다. 소유주를 선점 할 수없고 중요 섹션이 부족한 경우에만 스핀 잠금이보다 효율적으로 수행 될 수 있습니다. 쓰레드가 잠긴 뮤텍스를 얻으려고하면 커널은 여전히 ​​스핀 락을 얻어야한다.

개인적으로 필자는 공유 카운터 업데이트 및 더 복잡한 작업을위한 뮤텍스와 같은 것들에 대해 개인 작업을 사용합니다. 프로파일 링 후에 만 ​​뮤텍스를 스핀 잠금으로 대체하는 것을 고려할 것입니다 (그리고 선점을 처리하는 방법을 이해해야합니다). condvars를 사용하고자한다면 mutex를 사용하는 것 외에는 선택의 여지가 없다.

+0

와우 ... 그게 expalanation입니다 !! 정보의 큰 흐름에 감사드립니다.이 큰 게시물에 대해 많은 감사를드립니다! –