스핀락 예제

큰 커널 잠금 장치를 사용하는 것은 간단합니다. lock_kernel()을 호출하여 잠금을 획득하고 unlock_kernel()을 해제합니다. 루틴 커널_locked()는 잠금이 유지되는 경우 0이 아닌 경우 0이 아닌 경우 비0을 반환합니다. 예: 2.5 개발 커널(및 사용 가능한 패치가 있는 2.4)부터 Linux 커널은 완전히 선점할 수 있습니다. 이 기능을 사용하면 현재 프로세스가 커널에서 실행중인 경우에도 우선 순위가 높은 프로세스에서 프로세스를 선점할 수 있습니다. 선점 가능한 커널은 SMP의 많은 동기화 문제를 만듭니다. 고맙게도 커널 선점은 SMP 잠금에 의해 동기화되므로 대부분의 문제는 SMP 안전 코드를 작성하여 자동으로 해결됩니다. 그러나 몇 가지 새로운 잠금 문제가 도입되었습니다. 예를 들어 잠금은 암시적으로 잠겨 있지만(각 CPU에 고유하기 때문에 안전함) 커널 선점으로 필요하기 때문에 CPU당 데이터를 보호하지 못할 수 있습니다. 다음 예제에서는 SpinLock을 사용하는 방법을 보여 줍니다. 이 예제에서는 중요 섹션이 최소한의 작업을 수행하므로 SpinLock에 적합한 후보가 됩니다. 작업을 소량 늘리면 표준 잠금에 비해 SpinLock의 성능이 향상됩니다.

그러나 SpinLock이 표준 잠금보다 비용이 많이 드는 지점이 있습니다. 프로파일링 도구에서 동시성 프로파일링 기능을 사용하여 프로그램에서 더 나은 성능을 제공하는 잠금 유형을 확인할 수 있습니다. 자세한 내용은 동시성 시각화 도우미를 참조하십시오. 원자성 메서드의 다음 그룹은 개별 비트에서 작동하는 메서드입니다. 표준 C 데이터 형식에서 작동하기 때문에 정수 메서드보다 간단합니다. 예를 들어 void set_bit(int nr, void *addr)를 고려합니다. 이 함수는 애더가 가리키는 데이터의 „nr-th” 비트1로 원자적으로 설정됩니다. 원자비트 연산자는 „함수 참조” 사이드바에도 나열됩니다. 이 예제에서는 다중 스레드 액세스에 대한 사용자 동기화가 필요한 System.Collections.Generics.Generics.Queue 클래스를 사용합니다.

.NET Framework 버전 4를 대상으로 하는 응용 프로그램에서 다른 옵션은 사용자 잠금이 필요하지 않은 System.Collections.Concurrent.ConcurrentQueue를 사용하는 것입니다. 우리는 두 가지 이유로 처음에 원자 연산을 다룹니다. 첫째, 커널 동기화에 대한 가장 간단한 접근 방식이므로 이해하고 사용하기가 가장 쉽습니다. 둘째, 복잡한 잠금 프리미티브가 구축됩니다. 이러한 의미에서 커널 잠금의 구성 요소입니다. 원자 연산자는 하나의 중단 없는 작업에서 수행되는 추가 및 빼기와 같은 작업입니다. i++의 이전 예제를 고려합니다. 우리가 i를 읽고, 그것을 증분하고 하나의 중단할 수없는 작업으로 메모리에 다시 쓸 수 있다면 위에서 설명 한 경주 조건은 문제가되지 않을 것입니다.

원자 연산자는 이러한 무정전 작업을 제공합니다. 정수에서 작동하는 메서드와 비트에서 작동하는 메서드의 두 가지 유형이 있습니다. 정수 작업은 다음과 같이 작동합니다: 이전 자습서에서는 Mutex 및 구현의 사용을 이해했습니다. 뮤텍스를 이해했다면 스핀록도 비슷합니다. 둘 다 두 개 이상의 프로세스에 의해 동시에 수정 되지 않도록 공유 리소스를 보호 하는 데 사용 됩니다. 아래에 지정된 매크로를 사용하여 스핀록을 정적으로 초기화할 수 있습니다. 다음 예제에서는 x86 어셈블리 언어를 사용하여 스핀록을 구현합니다. 그것은 모든 인텔 80386 호환 프로세서에서 작동합니다. 이 코드 조각은 전역 변수(etx_gloabl_변수)에 액세스하는 두 개의 스레드를 만드는 방법을 설명합니다.

따라서 변수에 액세스하기 전에 스핀 록을 잠글 수 있습니다. 그 후 스핀 록을 해제합니다. 이 예제는 접근 방식 1을 사용하고 있습니다. Mutex 개념에서 스레드가 사용할 수 없는 Mutex를 잠그거나 획득하려고 할 때 해당 스레드는 뮤텍스를 사용할 수 있을 때까지 절전 모드로 이동합니다. 스핀 록에서는 다른 반면. 스핀록은 매우 간단한 단일 홀더 잠금 장치입니다.