뮤텍스는 멀티 스레딩 문제를 해결하는 데 자주 사용되는 프로그래밍 개념입니다. 커뮤니티에 대한 나의 질문 :
뮤텍스 란 무엇이며 어떻게 사용합니까?
뮤텍스는 멀티 스레딩 문제를 해결하는 데 자주 사용되는 프로그래밍 개념입니다. 커뮤니티에 대한 나의 질문 :
뮤텍스 란 무엇이며 어떻게 사용합니까?
답변:
직장에서 열띤 토론을 할 때 고무 닭을 사용하여 책상에 보관합니다. 닭을 안고있는 사람은 대화 할 수있는 유일한 사람입니다. 닭고기를 안들면 말할 수 없습니다. 닭고기를 원한다고 말하고 말하기 전에 닭고기를 먹을 때까지 기다리십시오. 말을 마치면 닭을 중재자에게 돌려주고 다음 사람에게 말을 건네줍니다. 이렇게하면 사람들이 서로 대화하지 않고 대화 할 공간이 생깁니다.
Chicken을 Mutex로 바꾸고 사람을 스레드로 바꾸면 기본적으로 mutex라는 개념이 있습니다.
물론 고무 뮤텍스와 같은 것은 없습니다. 고무 치킨 만. 내 고양이는 한때 고무 마우스를 먹었지 만 그것을 먹었습니다.
물론 고무 치킨을 사용하기 전에 실제로 한 방에 5 명이 필요한지 스스로에게 물어봐야하며 방에있는 한 사람이 혼자서 모든 일을하는 것이 더 쉬울 수는 없습니다. 실제로 이것은 유추를 확장 한 것이지만 아이디어를 얻습니다.
뮤텍스는 상호 배타적 인 플래그입니다. 하나의 스레드를 허용하고 다른 스레드에 대한 액세스를 차단하는 코드 섹션의 게이트 키퍼 역할을합니다. 이렇게하면 제어되는 코드가 한 번에 하나의 스레드 만 맞을 수 있습니다. 완료되면 뮤텍스를 해제하십시오. :)
상호 배제. 여기에 Wikipedia 항목이 있습니다.
http://en.wikipedia.org/wiki/Mutual_exclusion
뮤텍스의 요점은 두 개의 스레드를 동기화하는 것입니다. 단일 리소스에 액세스하려는 두 개의 스레드가있는 경우 일반적인 패턴은 코드를 입력하기 전에 첫 번째 코드 블록이 뮤텍스를 설정하기 위해 액세스를 시도하는 것입니다. 두 번째 코드 블록이 액세스를 시도하면 뮤텍스가 설정된 것을 확인하고 첫 번째 코드 블록이 완료 될 때까지 기다렸다가 뮤텍스를 설정 해제합니다.
이것이 어떻게 달성되는지에 대한 구체적인 내용은 프로그래밍 언어에 따라 크게 다릅니다.
다중 스레드 응용 프로그램을 사용하는 경우 다른 스레드가 변수 또는 이와 같은 공통 리소스를 공유하는 경우가 있습니다. 이 공유 소스는 종종 동시에 액세스 할 수 없으므로 한 번에 하나의 스레드 만 해당 자원을 사용하도록하는 구성이 필요합니다.
이 개념을 "상호 배제"(짧은 뮤텍스)라고하며, 해당 리소스 등을 사용하여 해당 영역 내에 하나의 스레드 만 허용되도록하는 방법입니다.
그것들을 사용하는 방법은 언어마다 다르지만 종종 운영 체제 뮤텍스를 기반으로합니다 (항상 그렇지는 않지만).
기능 프로그래밍과 같은 패러다임으로 인해 일부 언어에는이 구문이 필요하지 않습니다 (Haskell, ML이 좋은 예입니다).
C #에서 사용되는 공통 뮤텍스는 Monitor 입니다. 유형은 ' System.Threading.Monitor '입니다. ' lock (Object) '문을 통해 암시 적으로 사용될 수도 있습니다 . 사용의 한 예는 Singleton 클래스를 생성 할 때입니다.
private static readonly Object instanceLock = new Object();
private static MySingleton instance;
public static MySingleton Instance
{
lock(instanceLock)
{
if(instance == null)
{
instance = new MySingleton();
}
return instance;
}
}
개인 잠금 오브젝트를 사용하는 잠금 문은 중요한 섹션을 작성합니다. 각 스레드가 이전 스레드가 완료 될 때까지 대기하도록 요구합니다. 첫 번째 스레드는 섹션으로 들어가 인스턴스를 초기화합니다. 두 번째 스레드는 대기하고 섹션으로 이동하여 초기화 된 인스턴스를 가져옵니다.
정적 멤버의 모든 종류의 동기화는 lock 문을 유사하게 사용할 수 있습니다.
무엇 뮤텍스는 ?
스핀 록 (spinlock)이라고도하는 뮤텍스 (사실 뮤텍스라는 용어는 중요한 부분을 보호하고 경쟁 조건을 방지하는 데 사용되는 가장 간단한 동기화 도구)입니다. 즉, 스레드는 임계 섹션에 들어가기 전에 잠금을 획득해야합니다 (중요 섹션에서 다중 스레드는 공통 변수를 공유하고, 테이블을 업데이트하고 파일을 작성하는 등) 임계 섹션을 떠날 때 잠금을 해제합니다.
경쟁 조건 이란 무엇입니까 ?
경쟁 조건은 둘 이상의 스레드가 공유 데이터에 액세스 할 수 있고 동시에 변경하려고 할 때 발생합니다. 스레드 예약 알고리즘은 언제든지 스레드간에 교환 할 수 있으므로 스레드가 공유 데이터에 액세스하려는 순서를 모릅니다. 따라서, 데이터 변경의 결과는 스레드 스케줄링 알고리즘에 의존한다. 즉, 두 스레드 모두 데이터를 액세스 / 변경하기 위해 "경주"하고있다.
실제 예 :
직장에서 열띤 토론을 할 때, 나는 그런 경우를 위해 책상에 두는 고무 치킨을 사용합니다. 닭을 안고있는 사람은 대화 할 수있는 유일한 사람입니다. 닭고기를 안들면 말할 수 없습니다. 닭고기를 원한다는 말만하고 말하기 전에 닭이 나올 때까지 기다리십시오. 말을 마치면 닭고기를 다음 사람에게 건네주는 중재자에게 닭을 돌려 줄 수 있습니다. 이렇게하면 사람들이 서로 대화하지 않고 대화 할 공간이 생깁니다.
Chicken을 Mutex로 바꾸고 사람을 스레드로 바꾸면 기본적으로 mutex라는 개념이 있습니다.
X
C #에서의 사용법 :
이 예는 로컬 Mutex 객체를 사용하여 보호 된 리소스에 대한 액세스를 동기화하는 방법을 보여줍니다. 각 호출 스레드는 뮤텍스의 소유권을 얻을 때까지 차단되므로 스레드의 소유권을 해제하려면 ReleaseMutex 메소드를 호출해야합니다.
using System;
using System.Threading;
class Example
{
// Create a new Mutex. The creating thread does not own the mutex.
private static Mutex mut = new Mutex();
private const int numIterations = 1;
private const int numThreads = 3;
static void Main()
{
// Create the threads that will use the protected resource.
for(int i = 0; i < numThreads; i++)
{
Thread newThread = new Thread(new ThreadStart(ThreadProc));
newThread.Name = String.Format("Thread{0}", i + 1);
newThread.Start();
}
// The main thread exits, but the application continues to
// run until all foreground threads have exited.
}
private static void ThreadProc()
{
for(int i = 0; i < numIterations; i++)
{
UseResource();
}
}
// This method represents a resource that must be synchronized
// so that only one thread at a time can enter.
private static void UseResource()
{
// Wait until it is safe to enter.
Console.WriteLine("{0} is requesting the mutex",
Thread.CurrentThread.Name);
mut.WaitOne();
Console.WriteLine("{0} has entered the protected area",
Thread.CurrentThread.Name);
// Place code to access non-reentrant resources here.
// Simulate some work.
Thread.Sleep(500);
Console.WriteLine("{0} is leaving the protected area",
Thread.CurrentThread.Name);
// Release the Mutex.
mut.ReleaseMutex();
Console.WriteLine("{0} has released the mutex",
Thread.CurrentThread.Name);
}
}
// The example displays output like the following:
// Thread1 is requesting the mutex
// Thread2 is requesting the mutex
// Thread1 has entered the protected area
// Thread3 is requesting the mutex
// Thread1 is leaving the protected area
// Thread1 has released the mutex
// Thread3 has entered the protected area
// Thread3 is leaving the protected area
// Thread3 has released the mutex
// Thread2 has entered the protected area
// Thread2 is leaving the protected area
// Thread2 has released the mutex
여기에 훌륭한 답변이 있습니다. 여기에 뮤텍스 가 무엇인지 설명하는 또 다른 훌륭한 비유 가 있습니다.
열쇠 가있는 싱글 화장실을 고려하십시오 . 누군가가 들어 오면 열쇠를 가져 가고 화장실이 차지 합니다. 다른 사람이 화장실을 사용해야하는 경우 대기열 에서 기다려야합니다 . 화장실에있는 사람이 끝나면 키를 대기열에있는 다음 사람에게 전달합니다. 이해가 되나요?
변환 화장실을 A와 스토리에 공유 자원 , 그리고 키 A와 뮤텍스 . 화장실 열쇠를 가져 가면 (자물쇠 획득) 사용할 수 있습니다. 키가없는 경우 (잠금이 잠김) 기다려야합니다. 사람이 열쇠를 반환하면 ( 자물쇠를 놓음 ) 이제 열쇠 를 얻을 수 있습니다.
처음에 MUTEX를 이해하려면 "경주 조건"이 무엇인지 알아야하며 MUTEX이 필요한 이유 만 이해하게됩니다. 다중 스레딩 프로그램이 있고 두 개의 스레드가 있다고 가정하십시오. 이제 작업 대기열에 하나의 작업이 있습니다. 첫 번째 스레드는 작업 큐를 확인하고 작업을 찾은 후 실행을 시작합니다. 두 번째 스레드는 작업 대기열을 확인하고 대기열에 작업이 하나 있음을 발견합니다. 따라서 동일한 작업 포인터도 할당합니다. 이제 두 스레드가 동일한 작업을 실행하고 있습니다. 이로 인해 분할 오류가 발생합니다. 이것이 경쟁 조건의 예입니다.
이 문제에 대한 해결책은 MUTEX입니다. MUTEX는 한 번에 하나의 스레드를 잠그는 일종의 잠금 장치입니다. 다른 스레드가이를 잠 그려면 스레드가 단순히 차단됩니다.
이 pdf 파일 링크 의 MUTEX 주제 는 실제로 읽을 가치가 있습니다.
Mutex : Mutex는 Mut ual Ex를 나타냅니다 clusion. 한 번에 하나의 프로세스 / 스레드가 중요한 섹션으로 들어갈 수 있음을 의미합니다. 여러 스레드 / 프로세스가 공유 리소스 (변수, 공유 메모리 등)를 업데이트하려고하는 동시 프로그래밍에서 예기치 않은 결과가 발생할 수 있습니다. (결과는 어느 스레드 / 프로세스가 첫 번째 액세스 권한을 갖는지에 따라 다릅니다).
이러한 예기치 않은 결과를 피하기 위해서는 한 번에 하나의 스레드 / 프로세스 만 해당 리소스에 액세스 할 수 있도록 동기화 메커니즘이 필요합니다.
pthread 라이브러리는 Mutex를 지원합니다.
typedef union
{
struct __pthread_mutex_s
{
***int __lock;***
unsigned int __count;
int __owner;
#ifdef __x86_64__
unsigned int __nusers;
#endif
int __kind;
#ifdef __x86_64__
short __spins;
short __elision;
__pthread_list_t __list;
# define __PTHREAD_MUTEX_HAVE_PREV 1
# define __PTHREAD_SPINS 0, 0
#else
unsigned int __nusers;
__extension__ union
{
struct
{
short __espins;
short __elision;
# define __spins __elision_data.__espins
# define __elision __elision_data.__elision
# define __PTHREAD_SPINS { 0, 0 }
} __elision_data;
__pthread_slist_t __list;
};
#endif
이것은 뮤텍스 데이터 형식, 즉 pthread_mutex_t의 구조입니다. 뮤텍스가 잠기면 __lock은 1로 설정되고, 잠금이 해제되면 __lock은 0으로 설정됩니다.
이렇게하면 두 프로세스 / 스레드가 동시에 중요한 섹션에 액세스 할 수 없습니다.