2009-08-10 3 views
4

Windows는 스레드 (예 : SetEventWaitForSingleObject), 뮤텍스 및 중요 섹션과 같은 스레드 동기화에 유용한 여러 개체를 제공합니다.라이브러리가 Windows에서 기본 잠금을 구현하는 이유는 무엇입니까?

필자는 개인적으로 항상 중요한 부분을 사용했습니다. 왜냐하면 이미 잠겨 있지 않은 한 거의 모든 오버 헤드가 발생하지 않기 때문입니다. 그러나 부스트와 같은 여러 라이브러리를 살펴보면 Windows에서 연동 된 메서드를 사용하여 자체 잠금을 구현하는 데 많은 어려움을 겪게됩니다.

사람들이 특수화 된 사례가 있기 때문에 사람들이 자물쇠가없는 대기열을 작성하는 이유를 이해할 수 있지만 사람들이 기본 동기화 객체의 자체 버전을 구현하는 이유가 무엇입니까?

답변

14

라이브러리가 자체 잠금을 구현하지 않습니다. OS 지원 없이는 거의 불가능합니다.

무엇이 입니까?은 단순히 OS 제공 잠금 장치를 래핑하는 것입니다.

부스트는 몇 가지 이유를 수행합니다

  • 그들은 C++ 기능을 활용, 더 나은 설계 잠금 API를 제공 할 수있게되었습니다. Windows API는 C로만 작성되었으며, 잘 설계된 C가 아닙니다.
  • 그들은 이식성을 제공 할 수 있습니다. Linux 시스템이나 Mac에서 애플리케이션을 실행하는 경우 동일한 Boost API를 사용할 수 있습니다. Windows 고유의 API는 분명 Windows 특유의 것입니다.
  • Windows에서 제공하는 메커니즘에는 다음과 같은 단점이 있습니다. windows.h을 포함해야합니다. 많은 경우, 특히 전역 네임 스페이스를 극단적 인 매크로 남용으로 피하는 것이 좋습니다.
+0

boost \ thread \ win32 \ basic_timed_mutex.hpp에서 보니 win32 스레딩 객체의 사용은 전혀 보이지 않습니다. 어쨌든 특수한 CPU 명령어를 사용하는 인터 로킹 된 메소드로 처리되는 것처럼 보입니다. –

+2

연동 된 메서드는 일부 Win32 동기화 개체의 기초이기도합니다. 뮤텍스 또는 선택을 위해 실제로 필요한 모든 것입니다. – Blindy

+0

인터록 된 메서드는 Win32 API의 일부이기도합니다. 상위 수준의 Win32 동기화 개체보다 이식성이 뛰어납니다. – jalf

4

제가 생각할 수있는 특별한 이유 중 하나는 이식성입니다. Windows 잠금은 자체적으로 훌륭하지만 다른 플랫폼으로 이식 할 수 없습니다. 이식 가능한 라이브러리는 여러 플랫폼에서 동일한 의미를 보장하기 위해 자체 잠금을 구현해야합니다.

+0

기본적으로 인터 로킹 된 방법을 사용하여 Windows 코드를 향상시키는 것은 기본적으로 pthreads와 동일하게 작동하는 디자인입니다. 다른 플랫폼? –

+0

@ Fire Lancer, 네, 추측 ** ** 그 경우입니다. – JaredPar

1

라이브러리를위한 잠금 코드 작성은 해당 라이브러리가 크로스 플랫폼을위한 것이라면 유용합니다. 라이브러리 사용자는 라이브러리의 잠금 기능을 사용할 수 있으며 기본 플랫폼 구현에 신경 쓸 필요가 없습니다. 라이브러리에 대상이되는 모든 플랫폼의 버전이 있다고 가정하면 이식해야 할 코드가 하나 줄어 듭니다.

+0

JaredPar가 동일한 답변을 게시했습니다 –

2
  1. 많은 라이브러리 (일명 부스트)에서 corss 플랫폼 코드를 작성해야합니다. 따라서 WaitForSingleObject와 SetEvent를 사용하는 것은 아무 것도하지 않습니다. 또한 Monitors, Win32 API가 그리워하는 조건과 같은 일반적인 관용구가 있습니다 (그러나이 기본 프리미티브를 사용하여 구현할 수 있습니다)
  2. 원자 카운터와 같은 일부 잠금없는 데이터 구조는 매우 유용합니다. 예를 들어, boost::shared_ptr은 임계 섹션의 오버 헤드없이 스레드를 안전하게 유지하기 위해이를 사용합니다. 대부분의 컴파일러 (msvc 아님)는 쓰레드 안전 복사시 쓰기 std::string을 구현하기 위해 원자 카운터를 사용합니다.
  3. 대기열과 같은 일부 기능은 특정 응용 프로그램에서 중요한 성능 향상을 가져올 수있는 잠금이 전혀없는 스레드 안전 방식으로 매우 효율적으로 구현할 수 있습니다.
2

Windows OS 동기화 개체를 사용하지 않는 자체 잠금을 구현하는 데는 좋은 이유가있을 수 있습니다. 그러나 이렇게하는 것은 "날카로운 막대기"입니다."발에서 몸을 찌르는 것이 쉽습니다.

다음은 예입니다. 하드웨어 컨텍스트와 동일한 수의 스레드를 실행 중이며 대기중인 스레드 중 하나를 깨우는 대기 시간 잠금 장치가 매우 중요하기 때문에 사용자 공간에서 완전히 구현 된 스핀 잠금 장치를 선택할 수 있습니다. 대기중인 스레드가 잠금 장치에서 회전하는 유일한 스레드 인 경우 잠금 장치를 소유 한 스레드에서 대기중인 스레드로 전송하는 대기 시간 동일한 상황에서 OS 잠금을 가진 스레드에 신호를 보내는 대기 시간보다 훨씬 빠른 속도로 오너 스레드와 캐시 스레드를 대기 스레드로 이동하는 지연 일뿐입니다.

하지만 시나리오 이렇게하기를 원한다면 꽤 좁습니다. 하드웨어 쓰레드보다 더 많은 소프트웨어 쓰레드를 갖기 시작할 때, 아마 후회할 것입니다. 이 시나리오에서는 스핀 락을 돌리고 아무것도하지 않고 전체 OS 스케줄링 퀀텀을 보낼 수 있습니다. 또한 전력을 신경 쓰면 스핀 록이 프로세서가 저전력 상태가되는 것을 방지하기 때문에 좋지 않습니다.

나는 이식성 주장을 잘 모르겠다. 휴대용 라이브러리에는 동기화를 위해 다양한 OS API를 추상화하는 OS 이식성 계층이 있습니다. 잠금을 다루는 경우 pthread_mutex는 의미 상으로 추상화 계층 아래의 Windows Mutex 또는 중요 섹션과 동일하게 만들 수 있습니다. 여기에 몇 가지 예외가 있지만 대부분의 사람들에게 이것은 사실입니다. Windows Events 나 POSIX 조건 변수를 다루는 사람이라면 추상화하기가 더 어렵습니다. (비스타는 POSIX 스타일의 조건 변수를 도입했지만 많은 Windows 소프트웨어 개발자가 Vista를 요구하는 위치에 있지는 않습니다 ...)

관련 문제