[windows] 뮤텍스와 크리티컬 섹션의 차이점은 무엇입니까?

리눅스, Windows 관점에서 설명해주세요.

나는 C #으로 프로그래밍하고 있는데,이 두 용어가 차이를 만들 것입니다. 예를 들어 가능한 한 많이 게시하십시오 ….

감사



답변

Windows의 경우 중요 섹션은 뮤텍스보다 가볍습니다.

뮤텍스는 프로세스간에 공유 될 수 있지만 항상 약간의 오버 헤드가있는 커널에 대한 시스템 호출이 발생합니다.

중요 섹션은 하나의 프로세스 내에서만 사용할 수 있지만 경합의 경우 커널 모드로만 전환 할 수 있다는 장점이 있습니다. 일반적이지 않은 비경쟁 획득은 매우 빠릅니다. 경합의 경우, 이벤트 또는 세마포어와 같은 일부 동기화 기본 요소를 대기하기 위해 커널로 들어갑니다.

나는 둘 사이의 시간을 비교하는 빠른 샘플 앱을 작성했습니다. 1,000,000 개의 비경쟁 획득 및 릴리스 시스템에서 뮤텍스가 1 초 이상 걸립니다. 1,000,000 획득에 중요한 섹션은 ~ 50 ms가 소요됩니다.

테스트 코드는 다음과 같습니다. mutex가 첫 번째 또는 두 번째 인 경우 비슷한 결과를 얻었으므로 다른 효과는 보이지 않습니다.

HANDLE mutex = CreateMutex(NULL, FALSE, NULL);
CRITICAL_SECTION critSec;
InitializeCriticalSection(&critSec);

LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
LARGE_INTEGER start, end;

// Force code into memory, so we don't see any effects of paging.
EnterCriticalSection(&critSec);
LeaveCriticalSection(&critSec);
QueryPerformanceCounter(&start);
for (int i = 0; i < 1000000; i++)
{
    EnterCriticalSection(&critSec);
    LeaveCriticalSection(&critSec);
}

QueryPerformanceCounter(&end);

int totalTimeCS = (int)((end.QuadPart - start.QuadPart) * 1000 / freq.QuadPart);

// Force code into memory, so we don't see any effects of paging.
WaitForSingleObject(mutex, INFINITE);
ReleaseMutex(mutex);

QueryPerformanceCounter(&start);
for (int i = 0; i < 1000000; i++)
{
    WaitForSingleObject(mutex, INFINITE);
    ReleaseMutex(mutex);
}

QueryPerformanceCounter(&end);

int totalTime = (int)((end.QuadPart - start.QuadPart) * 1000 / freq.QuadPart);

printf("Mutex: %d CritSec: %d\n", totalTime, totalTimeCS);


답변

이론적 인 관점에서 중요한 섹션 은 코드가 공유 리소스에 액세스하기 때문에 여러 스레드에서 한 번에 실행하면 안되는 코드입니다.

뮤텍스 임계 영역을 보호하기 위해 사용된다 (때로는 데이터 구조의 이름) 알고리즘이다.

세마포어모니터 는 뮤텍스의 일반적인 구현입니다.

실제로 Windows에서 사용 가능한 많은 뮤텍스 구현이 있습니다. 잠금 수준, 범위, 비용 및 다양한 수준의 경합에서 성능에 따라 구현 결과에 따라 다릅니다. 다양한 뮤텍스 구현 비용에 대한 차트는 확장 성위해 CLR 인사이드 아웃-동시성 사용을 참조하십시오 .

사용 가능한 동기화 기본 요소.

lock(object)문은 사용하여 구현됩니다 Monitor– 참조 MSDN을 참조.

지난 몇 년 동안 비 차단 동기화 에 대한 많은 연구가 이루어졌습니다 . 목표는 잠금 또는 대기없는 방식으로 알고리즘을 구현하는 것입니다. 이러한 알고리즘에서 프로세스는 다른 프로세스가 작업을 완료하도록 도와 프로세스가 최종적으로 작업을 완료 할 수 있도록합니다. 결과적으로 일부 작업을 수행하려는 다른 프로세스가 중단 된 경우에도 프로세스가 작업을 완료 할 수 있습니다. Usinig 잠금 장치는 잠금을 해제하지 않고 다른 프로세스가 계속 진행되지 않도록합니다.


답변

다른 답변 외에도 다음 세부 정보는 창의 중요 섹션에만 적용됩니다.

  • 경합이없는 경우 중요한 섹션을 얻는 것은 InterlockedCompareExchange작업 만큼 간단 합니다.
  • 임계 섹션 구조는 뮤텍스를위한 공간을 보유합니다. 처음에는 할당되지 않습니다
  • 임계 섹션에 대한 스레드간에 경합이있는 경우 뮤텍스가 할당되고 사용됩니다. 중요 섹션의 성능은 뮤텍스의 성능으로 저하됩니다
  • 높은 경합이 예상되는 경우 회전 수를 지정하여 중요 섹션을 할당 할 수 있습니다.
  • 스핀 수가있는 임계 섹션에 경합이있는 경우 임계 섹션을 획득하려는 스레드는 해당 프로세서주기 동안 스핀 (통화 대기)합니다. 다른 스레드로 컨텍스트 전환을 수행하는주기 수가 뮤텍스를 해제하기 위해 소유 한 스레드가 취하는주기 수보다 훨씬 높을 수 있으므로 휴면보다 성능이 향상 될 수 있습니다.
  • 스핀 카운트가 만료되면 뮤텍스가 할당됩니다
  • 소유하는 스레드가 임계 섹션을 해제 할 때 뮤텍스가 할당되었는지 확인해야합니다. 할당 된 경우 뮤텍스가 대기 스레드를 해제하도록 설정합니다.

리눅스에서 나는 그들이 스핀 카운트와 중요한 섹션과 유사한 목적을 제공하는 “스핀 잠금”을 가지고 있다고 생각합니다.


답변

중요 섹션 및 Mutex는 운영 체제별로 다르며 멀티 스레딩 / 멀티 프로세싱의 개념입니다.

중요 섹션
주어진 시간에 자체적으로 만 실행해야하는 코드입니다 (예 : 5 개의 스레드가 동시에 실행되고 “critical_section_function”이라는 함수가 배열을 업데이트합니다 … 5 개의 스레드를 모두 원하지는 않습니다. 따라서 프로그램이 critical_section_function ()을 실행할 때 다른 스레드는 critical_section_function을 실행해서는 안됩니다.

mutex *
Mutex는 임계 섹션 코드를 구현하는 방법입니다 (토큰처럼 생각하십시오. 스레드는 critical_section_code를 실행하기 위해이를 보유해야합니다).


답변

뮤텍스는 스레드가 획득 할 수있는 객체로, 다른 스레드가이를 획득하지 못하게합니다. 필수 사항이 아닌 권고입니다. 스레드는 뮤텍스가 나타내는 자원을 획득하지 않고 사용할 수 있습니다.

중요 섹션은 운영 체제에서 작동하지 않도록 보장되는 코드 길이입니다. 의사 코드에서는 다음과 같습니다.

StartCriticalSection();
    DoSomethingImportant();
    DoSomeOtherImportantThing();
EndCriticalSection();


답변

Linux에서 중요 선택과 동일한 ‘빠른’Windows는 futex 이며 이는 빠른 사용자 공간 뮤텍스를 나타냅니다. futex와 mutex의 차이점은 futex의 경우 중재가 필요할 때만 커널이 관여하므로 원자 카운터가 수정 될 때마다 커널과 통신하는 오버 헤드가 절약된다는 것입니다. .. 일부 응용 프로그램에서 잠금을 협상 하는 데 상당한 시간을 절약 할 수 있습니다 .

뮤텍스를 공유하기 위해 사용하는 수단을 사용하여 프로세스간에 퓨 텍스를 공유 할 수도 있습니다.

불행하게도, futex는 구현하기매우 까다로울 수 있습니다 (PDF). (2018 업데이트, 그들은 2009 년만큼 거의 무섭지 않습니다).

그 외에도 두 플랫폼에서 거의 동일합니다. 기아를 유발하지 않는 방식으로 공유 구조에 대한 원 자성 토큰 기반 업데이트를 만들고 있습니다. 남아있는 것은 단순히 그것을 달성하는 방법입니다.


답변

Windows에서 중요 섹션은 프로세스의 로컬입니다. 뮤텍스는 프로세스간에 공유 / 액세스 할 수 있습니다. 기본적으로 중요한 섹션은 훨씬 저렴합니다. Linux에 대해서는 구체적으로 언급 할 수 없지만 일부 시스템에서는 동일한 것의 별칭 일뿐입니다.