중첩된 잠금으로 인해 교착 상태가 발생하지 않는 이유는 무엇입니까?
왜 이 코드는 교착 상태를 일으키지 않습니까?
private static readonly object a = new object();
...
lock(a)
{
lock(a)
{
....
}
}
스레드가 이미 잠금을 보유하고 있으면 문제 없이 다시 "잠금"할 수 있습니다.
그 이유에 대해, (그리고 그것이 좋은 생각인 이유에 대해) a -> b 프로그램의 다른 곳에 정의된 잠금 순서가 있는 다음 상황을 고려합니다.
void f()
{
lock(a)
{ /* do stuff inside a */ }
}
void doStuff()
{
lock(b)
{
//do stuff inside b, that involves leaving b in an inconsistent state
f();
//do more stuff inside b so that its consistent again
}
}
이런, 우리는 방금 우리의 잠금 명령을 위반했고 우리의 손에 잠재적인 교착 상태에 빠졌습니다.
우리는 정말로 다음과 같은 일을 할 수 있어야 합니다.
function doStuff()
{
lock(a)
lock(b)
{
//do stuff inside b, that involves leaving b in an inconsistent state
f();
//do more stuff inside b so that its consistent again
}
}
전화를 걸 때 자동으로 잠금 해제되지 않고 잠금 순서를 유지할 수 있습니다.f()
.
그lock
키워드는 재인식 잠금을 사용합니다. 즉, 현재 스레드가 이미 잠금을 가지고 있으므로 재인식을 시도하지 않습니다.
다음과 같은 경우 교착 상태가 발생합니다.
스레드 1이 잠금 A를 획득합니다.
스레드 2가 잠금 B를 획득합니다.
스레드 1은 잠금 B(스레드 2가 완료될 때까지 대기)를 획득하려고 시도하고 스레드 2는 잠금 A(스레드 1이 완료될 때까지 대기)를 획득하려고 시도합니다.
이제 두 스레드가 서로 대기 중이므로 교착 상태에 빠집니다.
상호 제외 잠금이 유지되는 동안 동일한 실행 스레드에서 실행되는 코드도 잠금을 가져오고 해제할 수 있습니다.그러나 다른 스레드에서 실행되는 코드는 잠금이 해제될 때까지 잠금을 얻지 못하도록 차단됩니다.
내부적으로 볼 때,lock
스코프가 외부와 동일한 스레드에 있습니다.
언급URL : https://stackoverflow.com/questions/5035126/why-do-nested-locks-not-cause-a-deadlock
'programing' 카테고리의 다른 글
SQL Server에서 트랜잭션을 롤백하거나 커밋하는 방법 (0) | 2023.07.17 |
---|---|
홈브루를 사용하여 이전 버전의 파이썬 3을 macOS에 설치하려면 어떻게 해야 합니까? (0) | 2023.07.17 |
Git Submodule HEAD가 마스터에서 분리되는 이유는 무엇입니까? (0) | 2023.07.17 |
C/C++ 컴파일러가 컴파일 시 배열의 크기를 알아야 하는 이유는 무엇입니까? (0) | 2023.07.17 |
Mongoose와 함께 대량 상승을 시도하고 있습니다.가장 깨끗한 방법은 무엇입니까? (0) | 2023.07.17 |