spin_lock 예제

읽기 잠금 장치를 제거하려면 어떻게 해야 합니까? 읽기 잠금을 제거하면 작성기가 판독기 아래에 있는 목록을 변경할 수 있습니다. 이는 실제로 매우 간단합니다: 작성자가 요소를 매우 신중하게 추가하는 경우 요소가 추가되는 동안 연결된 목록을 읽을 수 있습니다. 예를 들어 목록이라는 단일 연결된 목록에 새 추가: 원자성 메서드의 다음 그룹은 개별 비트에서 작동하는 그룹입니다. 표준 C 데이터 형식에서 작동하기 때문에 정수 메서드보다 간단합니다. 예를 들어 void set_bit(int nr, void *addr)를 고려합니다. 이 함수는 애더가 가리키는 데이터의 “nr-th” 비트1로 원자적으로 설정됩니다. 원자비트 연산자는 “함수 참조” 사이드바에도 나열됩니다. 이름 매핑에 대한 숫자 캐시라는 간단한 예제를 살펴보겠습니다. 캐시는 각 개체가 사용되는 빈도를 유지하며, 개체가 가득 차면 가장 적게 사용되는 개체를 throw합니다. hb->잠금은 호출자에 의해 유지되어야 하며 여기에서 해제되어야 합니다. queue_me()에 대한 호출은 일반적으로 unqueue_me()에 대한 정확히 하나의 호출과 쌍을 이룹니다. 예외는 unqueue_me_pi() 또는 큐 해제가 절전 모드 해제 프로세스의 일부로 수행되고 큐 해제 상태가 깨어있는 작업 의 상태에서 암시적인 경우 unqueue_me_pi() 또는 아무것도 사용할 수 있는 PI 관련 작업을 포함합니다(예: futex_wait_requeue_pi(참조). 이 두 가지 모두 교착 상태라고 하며, 위에서 설명한 것처럼 단일 CPU에서도 발생할 수 있습니다(UP 컴파일에는 없지만 CONFIG_SMP=n을 가진 커널 컴파일에서 스핀록이 사라지기 때문에) 발생할 수 있습니다.

두 번째 예제에서는 여전히 데이터 손상이 있습니다. 이 두 가지 목표는 잠금을 잠시 동안 유지하면 잠금을 부분으로 분할하여 수행할 수 있지만(예: 최종 개체당 잠금 예제) 잠금 수집 수가 증가하고 결과가 단일 잠금을 갖는 것보다 느린 경우가 많습니다. 이것은 잠금 단순성을 옹호하는 또 다른 이유입니다. x86 아키텍처의 이후 구현에서 spin_unlock은 느린 잠긴 XCHG 대신 잠금 해제된 MOV를 안전하게 사용할 수 있습니다. MOV가 전체 메모리 장벽이 아니더라도 이를 지원하는 미묘한 메모리 정렬 규칙 때문입니다. 그러나 일부 프로세서 (일부 Cyrix 프로세서, 인텔 펜티엄 Pro의 일부 개정 (버그로 인해), 이전 펜티엄 및 i486 SMP 시스템)은 잘못된 일을하고 잠금으로 보호 된 데이터가 손상 될 수 있습니다. 대부분의 x86 아키텍처에서 명시적 메모리 장벽 또는 원자성 명령(예에서와 같이)을 사용해야 합니다. IA-64와 같은 일부 시스템에서는 필요한 메모리 순서를 제공하는 특별한 “잠금 해제” 지침이 있습니다.

이 간단한 예제 외에도 동기화 프리미티브는 Linux 커널에서 유비쿼터스입니다. 이전 장이나 다른 장을 다시 살펴보거나 일반적으로 Linux 커널 소스 코드를 살펴보면 다음과 같은 많은 장소를 만날 것입니다. Linux 커널에서 뮤텍스가 어떻게 구현되는지는 고려하지 않습니다. 실제로 Linux 커널은 다음과 같은 다른 동기화 프리미티브 집합을 제공합니다: 설명: 시스템이 잠금이 사용 중인 동안 스핀 잠금을 초기화하거나 파괴하려는 시도를 감지했습니다(예: pthread_spin_lock() 호출에서 사용 중). 다른 스레드. 커널/시간/clocksource.c 소스 코드 파일에서 확인할 수 있습니다. 이 코드는 지정된 클럭 소스를 클럭 소스 목록에 추가하는 __clocksource_register_scale 함수에서 가져옵니다. 이 함수는 등록된 클럭 원본이 있는 목록에서 서로 다른 작업을 생성합니다.