리눅스, 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에 대해서는 구체적으로 언급 할 수 없지만 일부 시스템에서는 동일한 것의 별칭 일뿐입니다.