{"componentChunkName":"component---src-templates-blog-post-js","path":"/Operating-Systems/2020-05-28-운영체제-데드락해결안/","result":{"data":{"site":{"siteMetadata":{"title":"Hun's Footsteps 🥷","author":"전여훈","siteUrl":"https://jeonyeohun.netlify.app","comment":{"disqusShortName":"","utterances":"jeonyeohun/jeonyeohun.github.io"},"sponsor":{"buyMeACoffeeId":"jeonyeohun"}}},"markdownRemark":{"id":"66d3967e-affc-5153-b66c-6478d1798f65","excerpt":"참고도서: Operating System Concepts (10/E) Abraham Silberschatz, Peter B. Galvin, Greg Gagne Resource Deadlock 교착상태는 일반적으로 지금까지 다뤄왔던 자원을 점유하는 상황 속에서 발생하는  과 스레드간 통신 상황에서 발생하는  으로 나뉜다. Communication deadlock은 정형화된 해결안이나 알고리즘이 없어 우리는 이번에도 역시 resource deadlock…","html":"<p>참고도서: <em>Operating System Concepts (10/E) Abraham Silberschatz, Peter B. Galvin, Greg Gagne</em></p>\n<h2 id=\"resource-deadlock\" style=\"position:relative;\"><a href=\"#resource-deadlock\" aria-label=\"resource deadlock permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Resource Deadlock</h2>\n<p>교착상태는 일반적으로 지금까지 다뤄왔던 자원을 점유하는 상황 속에서 발생하는 <code class=\"language-text\">resource deadlock</code> 과 스레드간 통신 상황에서 발생하는 <code class=\"language-text\">communication deadlock</code> 으로 나뉜다. Communication deadlock은 정형화된 해결안이나 알고리즘이 없어 우리는 이번에도 역시 resource deadlock을 해결하는 방법에 대해서 다루게될 것이다.</p>\n<h2 id=\"cyclic-deadlock-monitoring-algorithm\" style=\"position:relative;\"><a href=\"#cyclic-deadlock-monitoring-algorithm\" aria-label=\"cyclic deadlock monitoring algorithm permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Cyclic Deadlock Monitoring Algorithm</h2>\n<p>이 알고리즘은 프로세스가 자원을 점유할 때마다 그래프를 만들어서 사이클이 존재하는지 확인하는 방법이다. 뜬금없이 사이클이 왜 나오나 싶겠지만 이 알고리즘에서 사이클이 존재한다는 것은 자원을 점유한 상태에서 두 프로세스가 서로에게 자원을 요청하는 상태를 가르킨다. 알고리즘을 조금 더 자세히 보면 이해가 될 것이다. 프로세스가 실행중에 자원을 점유하고 해제할 때, 다음과 같은 과정으로 그래프를 만들게 된다.</p>\n<ol>\n<li>프로세스 N이 자원을 lock X를 통해 자원을 획득하게 되면, N<sub>x</sub> 라는 노드를 하나 만든다.</li>\n<li>만약 이 프로세스가 lock X를 점유하는 중에 lock Y를 점유하려고 하게되면 (N<sub>x</sub>, N<sub>y</sub>) 의 간선을 하나 만든다.</li>\n<li>lock X가 해제되면 N<sub>x</sub>와 연결된 모든 간선을 삭제한다.</li>\n</ol>\n<p>다음 예시를 통해 교착상태가 발생할 가능성이 있는지 확인해보자.</p>\n<h3 id=\"example\" style=\"position:relative;\"><a href=\"#example\" aria-label=\"example permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Example</h3>\n<p>Thread 1</p>\n<div class=\"gatsby-highlight\" data-language=\"cpp\"><pre class=\"language-cpp\"><code class=\"language-cpp\"><span class=\"token function\">lock</span><span class=\"token punctuation\">(</span>X<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span>\n<span class=\"token function\">lock</span><span class=\"token punctuation\">(</span>Y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span>\n<span class=\"token function\">unlock</span><span class=\"token punctuation\">(</span>Y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">unlock</span><span class=\"token punctuation\">(</span>X<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Thread 2</p>\n<div class=\"gatsby-highlight\" data-language=\"cpp\"><pre class=\"language-cpp\"><code class=\"language-cpp\"><span class=\"token function\">lock</span><span class=\"token punctuation\">(</span>Y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span>\n<span class=\"token function\">lock</span><span class=\"token punctuation\">(</span>X<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span>\n<span class=\"token function\">unlock</span><span class=\"token punctuation\">(</span>X<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">unlock</span><span class=\"token punctuation\">(</span>Y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>먼저 두 스레드가 실행되면서 각 명령어가 실행되는 순서에는 차이가 있을 수 있다. 그렇기 때문에 교착상태는 항상 발생하는 것이 아니고 특정한 상황이 성립되었을 때만 발생한다. 위 두 개의 스레드도 얼마든지 다른 순서로 실행될 수 있지만 다음과 같이 실행되는 상황을 생각해보자</p>\n<ol>\n<li>Thread 1이 lock X를 점유한다(<code class=\"language-text\">lock(X)</code>) : 이때 Cyclic Deadlock Monitoring Algorithm에 의해 N<sub>x</sub> 의 노드가 하나 만들어진다.</li>\n<li>Thread 2가 lock Y를 점유한다(<code class=\"language-text\">lock(Y)</code>) : 이때 역시 새로운 점유가 발생했기 때문에 N<sub>y</sub> 노드를 하나 생성한다.</li>\n<li>Thread 1이 lock Y를 점유하려고 시도한다(<code class=\"language-text\">lock(Y)</code>) : 이미 lock X 를 점유한 상태에서 lock Y의 점유를 시도하기 때문에, 알고리즘에 따라 N<sub>x</sub>와 N<sub>y</sub> 사이에 간선을 만든다.</li>\n<li>Thread 2가 lock X를 점유하려고 시도한다(<code class=\"language-text\">lock(X)</code>) : 이미 lock Y 를 점유한 상태에서 lock X의 점유를 시도하기 때문에, 알고리즘에 따라 N<sub>y</sub>와 N<sub>x</sub> 사이에 간선을 만든다.</li>\n</ol>\n<p>이때 두 스레드가 만든 그래프 안에 사이클이 발생했기 때문에, 프로그램은 교착상태에 대한 경고를 사용자에게 알릴 수 있다.</p>\n<h2 id=\"potential-cyclic-deadlock-detection-algorithm\" style=\"position:relative;\"><a href=\"#potential-cyclic-deadlock-detection-algorithm\" aria-label=\"potential cyclic deadlock detection algorithm permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Potential Cyclic Deadlock Detection Algorithm</h2>\n<p>위에서 사용한 알고리즘은 실제로 교착상태가 발생하는 순서로 프로세스가 실행됐을 때만 교착상태를 판단할 수 있다. 그렇다면 잠재되어 있는 교착상태의 위험에 대해 대처할 수 있는 알고리즘은 없을까? Potentail Cyclic Deadlock Detection Algorithm 은 이름이 말해주는 것처럼 교착상태가 일어날 수 있는 상황을 판별하는 알고리즘이다. 위 알고리즘과 큰 차이는 없지만 lock을 해제할 때, 간선을 삭제해주지 않고 그대로 유지한다는 점이 다르다. 따라서 이 알고리즘의 흐름을 정리해보면 다음과 같다.</p>\n<ol>\n<li>프로세스 N이 lock X를 점유하게 되면, 노드 N<sub>x</sub> 를 생성한다.</li>\n<li>프로세스 N이 lock X를 점유한 상태에서 lock Y를 점유하려고 하면 (N<sub>x</sub>, N<sub>y</sub>) 의 간선을 하나 만든다.</li>\n</ol>\n<p>이렇게 하면 한번 만들어진 사이클은 프로세스가 종료될 때까지 남아있기 때문에, 실제로 교착상태가 발생하지 않았다고 해도 사용자에게 교착상태가 일어날 위험성이 있다는 것을 알릴 수 있다.</p>\n<h2 id=\"false-positive-cases\" style=\"position:relative;\"><a href=\"#false-positive-cases\" aria-label=\"false positive cases permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>False Positive Cases</h2>\n<p>기존 알고리즘을 보완한 Potential Cyclic Deadlock Detection Algorithm을 사용하면 완벽하게 교착상태의 발생 가능성을 막을 수 있을 것 같지만, 실상은 그렇지 않다. 실제로는 교착상태가 일어날 일이 없는데, 사이클 알고리즘이 교착상태로 오탐지할 수 있는 경우를 알아보자.</p>\n<h3 id=\"1-같은-스레드-안에서-만들어진-사이클\" style=\"position:relative;\"><a href=\"#1-%EA%B0%99%EC%9D%80-%EC%8A%A4%EB%A0%88%EB%93%9C-%EC%95%88%EC%97%90%EC%84%9C-%EB%A7%8C%EB%93%A4%EC%96%B4%EC%A7%84-%EC%82%AC%EC%9D%B4%ED%81%B4\" aria-label=\"1 같은 스레드 안에서 만들어진 사이클 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. 같은 스레드 안에서 만들어진 사이클</h3>\n<p>Thread 1</p>\n<div class=\"gatsby-highlight\" data-language=\"cpp\"><pre class=\"language-cpp\"><code class=\"language-cpp\"><span class=\"token function\">lock</span><span class=\"token punctuation\">(</span>X<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">lock</span><span class=\"token punctuation\">(</span>Y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span>\n    <span class=\"token function\">unlock</span><span class=\"token punctuation\">(</span>Y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">unlock</span><span class=\"token punctuation\">(</span>X<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token function\">lock</span><span class=\"token punctuation\">(</span>Y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">lock</span><span class=\"token punctuation\">(</span>X<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span>\n    <span class=\"token function\">unlock</span><span class=\"token punctuation\">(</span>X<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">unlock</span><span class=\"token punctuation\">(</span>Y<span class=\"token punctuation\">)</span></code></pre></div>\n<p>위와 같이 한 스레드 안에서 두 번에 걸쳐 자원을 점유하는 로직이 있다고 해보자. 이 스레드는 가장 처음에 lock X를 점유한 채로 lock Y을 획득하려고 하기 때문에 X에 대한 노드와 해당 노드로 부터 Y노드로 향하는 간선을 가지게 된다. 그리고 작업을 마친 뒤 X와 Y를 해제하게 되는데, 이때 Potential Cyclic Deadlock Detection Algorithm 은 만들어진 간선을 해제하지 않기 때문에 노드와 간선이 남아있는 채로 계속 스레드가 실행된다.</p>\n<p>실행되던 스레드는 lock Y 를 획득하고 lock X를 점유하려고 한다. 이때 노드 Y가 생성되고 노드 Y로부터 노드 X로 연결되는 간선이 만들어진다. 즉, 사이클이 만들어지는 것이다.</p>\n<p>하지만 한 스레드 안에서는 교착상태가 발생할 수 없다. 따라서 이 경우에는 교착상태가 아니지만 알고리즘이 교착상태라고 오인하는 False Positive 가 발생한다.</p>\n<h3 id=\"2-게이트-락gate-lock이-있는-상황\" style=\"position:relative;\"><a href=\"#2-%EA%B2%8C%EC%9D%B4%ED%8A%B8-%EB%9D%BDgate-lock%EC%9D%B4-%EC%9E%88%EB%8A%94-%EC%83%81%ED%99%A9\" aria-label=\"2 게이트 락gate lock이 있는 상황 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. 게이트 락(Gate Lock)이 있는 상황</h3>\n<p>Thread 1</p>\n<div class=\"gatsby-highlight\" data-language=\"cpp\"><pre class=\"language-cpp\"><code class=\"language-cpp\"><span class=\"token function\">lock</span><span class=\"token punctuation\">(</span>X<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">lock</span><span class=\"token punctuation\">(</span>Y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token function\">lock</span><span class=\"token punctuation\">(</span>Z<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span>\n\n        <span class=\"token function\">unlock</span><span class=\"token punctuation\">(</span>Z<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">unlock</span><span class=\"token punctuation\">(</span>Y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">unlock</span><span class=\"token punctuation\">(</span>X<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Thread 2</p>\n<div class=\"gatsby-highlight\" data-language=\"cpp\"><pre class=\"language-cpp\"><code class=\"language-cpp\"><span class=\"token function\">f2</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n    <span class=\"token function\">lock</span><span class=\"token punctuation\">(</span>X<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token function\">lock</span><span class=\"token punctuation\">(</span>Z<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n            <span class=\"token function\">lock</span><span class=\"token punctuation\">(</span>Y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n            <span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span>\n\n            <span class=\"token function\">unlock</span><span class=\"token punctuation\">(</span>Y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token function\">unlock</span><span class=\"token punctuation\">(</span>Z<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">unlock</span><span class=\"token punctuation\">(</span>Y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>위 같이 두 개의 스레드가 실행되고 있다고 해보자. 중첩된 lock들을 보면 우리가 흔히 알고 있는 교착상태 패턴이다. Thread 1은 Y를 점유하는 중에 Z를 요구하게되고, Thread 2는 Z를 점유하는 중에 Y를 요구하게 된다.</p>\n<p>하지만 두 스레드 모두 중첩된 lock을 동일한 lock X 로 감싸고 있다. 따라서 Thread 1 이 lock을 획득하게되면, Thread 2는 lock Y 와 Z가 있는 구간에 절대 도달하지 못하기 때문에 상호배제가 보장되게 된다. 이렇게 두 스레드에서 사용되는 lock 들의 상호배제를 보장하는 lock을 <code class=\"language-text\">Gate Lock(혹은 Guard Lock)</code> 이라고 한다.</p>\n<p>이 경우에도 교착상태는 절대로 발생하지 않지만, 알고리즘으로 사이클을 검사하게 되면 X와 Y의 관계 때문에 사이클이 발생하게된다.</p>\n<h3 id=\"3-스레드가-스레드를-생성하는-상황\" style=\"position:relative;\"><a href=\"#3-%EC%8A%A4%EB%A0%88%EB%93%9C%EA%B0%80-%EC%8A%A4%EB%A0%88%EB%93%9C%EB%A5%BC-%EC%83%9D%EC%84%B1%ED%95%98%EB%8A%94-%EC%83%81%ED%99%A9\" aria-label=\"3 스레드가 스레드를 생성하는 상황 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. 스레드가 스레드를 생성하는 상황</h3>\n<p>Thread 1</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">lock(X);\n    lock(Y);\n    unlock(Y);\nunlock(X);\nstart(f2);</code></pre></div>\n<p>Thread 2</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">lock(Y);\n    lock(X);\n    unlock(X);\nunlock(Y);</code></pre></div>\n<p>위 경우에서도 X 와 Y 사이에서 교착상태가 일어나는 패턴이 발견된다. 그렇기 때문에 알고리즘은 여전히 사이클이 있는 그래프를 만들게 될 것이다.</p>\n<p>하지만 상식적으로 생각해보자. 교착상태는 실행 중인 두 프로세스나 스레드가 서로의 자원을 기다리게 되기 때문에 발생한다. 위 코드를 보면 Thread 1의 자원 점유와 해제 가 모두 끝난 뒤에 Thread 2를 생성한다. 따라서 Thread 1 과 Thread 2는 절대 병렬적으로 실행될 수 없는 스레드이지만 교착상태가 있을 것이라고 오탐지하는 것이다.</p>\n<h2 id=\"goodlock-algorithm\" style=\"position:relative;\"><a href=\"#goodlock-algorithm\" aria-label=\"goodlock algorithm permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>GoodLock Algorithm</h2>\n<p>GoodLock 알고리즘은 기존 Cyclic Deadlock Detection 알고리즘의 문제점이었던 오탐지 상황을 모두 보완한 알고리즘이다. 사이클을 탐지한다는 점에서 큰 그림은 비슷하지만 몇가지 다른 부분들이 있다.</p>\n<p>GoodLock 알고리즘은 앞서 설명했던 사이클의 세 가지 예외상황을 탐지하기 위해서 간선을 만들 때 몇가지 정보를 더 추가해서 간선은 만들게 되는데, 다음과 같이 정보를 구성한다.</p>\n<p>(노드1, (노드1의 코드 섹션, 간선을 만든 스레드의 아이디, Guard Lock 위치, 노드2의 코드 섹션) 노드2)</p>\n<p>헷갈리니까 좀 더 자세히 보자. 그리고 기억해야할 것은 사이클이 발생했다는 것은 위 간선 정보가 한 쌍으로 만들어진다는 것이다.</p>\n<ol>\n<li>노드 1, 노드 2: 사이클을 만드는 두 개의 노드</li>\n<li>코드 섹션: 두 노드간의 간선이 만들어진 코드블럭.</li>\n<li>간선을 만든 스레드 아이디</li>\n<li>Guard Lock 위치: 간선을 만든 lock들을 감싸고 있는 lock의 위치</li>\n</ol>\n<p>GoodLock 알고리즘은 그래프에서 사이클이 발생했을 때 위 정보를 가지고 해당 사이클이 교착상태에 유효한 사이클인지 확인하게 된다. 그럼 앞서서 지적되었던 false positive 상황들을 검사해보자.</p>\n<h3 id=\"1-같은-스레드-안에서-만들어진-사이클-1\" style=\"position:relative;\"><a href=\"#1-%EA%B0%99%EC%9D%80-%EC%8A%A4%EB%A0%88%EB%93%9C-%EC%95%88%EC%97%90%EC%84%9C-%EB%A7%8C%EB%93%A4%EC%96%B4%EC%A7%84-%EC%82%AC%EC%9D%B4%ED%81%B4-1\" aria-label=\"1 같은 스레드 안에서 만들어진 사이클 1 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. 같은 스레드 안에서 만들어진 사이클</h3>\n<p>(m<sub>11</sub>, (s<sub>11</sub>, t<sub>1</sub>, G<sub>1</sub>, s<sub>12</sub>),\nm<sub>12</sub>) <br>\n(m<sub>21</sub>, (s<sub>21</sub>, t<sub>2</sub>, G<sub>2</sub>,\ns<sub>22</sub>), m<sub>22</sub>)</p>\n<p>위와 같이 두개의 노드가 사이클을 만들었다고 해보자. 한 스레드 안에서는 병렬적으로 작업이 실행되는 것이 불가능하기 때문에 한 스레드안에서 만들어지는 사이클은 무의미하다. 따라서 두 간선 정보에서 스레드 아이디를 의미하는 t<sub>1</sub>과 t<sub>2</sub> 가 같은 값을 가지는지 확인하면 false positive 상황인지 쉽게 판별할 수 있게된다.</p>\n<h3 id=\"2-게이트-락gate-lock이-있는-상황-1\" style=\"position:relative;\"><a href=\"#2-%EA%B2%8C%EC%9D%B4%ED%8A%B8-%EB%9D%BDgate-lock%EC%9D%B4-%EC%9E%88%EB%8A%94-%EC%83%81%ED%99%A9-1\" aria-label=\"2 게이트 락gate lock이 있는 상황 1 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. 게이트 락(Gate Lock)이 있는 상황</h3>\n<p>게이트 락의 여부역시 두 간선이 가지는 G의 값을 확인하는 것으로 해결할 수 있다. 만약 두 G가 가지는 위치가 겹친다면, 둘은 같은 곳에 위치해 있다는 의미이기 때문에 스레드간의 상호배제를 보장하는 게이트 락의 역할을 하게된다.</p>\n<h3 id=\"3-스레드가-스레드를-생성하는-상황-1\" style=\"position:relative;\"><a href=\"#3-%EC%8A%A4%EB%A0%88%EB%93%9C%EA%B0%80-%EC%8A%A4%EB%A0%88%EB%93%9C%EB%A5%BC-%EC%83%9D%EC%84%B1%ED%95%98%EB%8A%94-%EC%83%81%ED%99%A9-1\" aria-label=\"3 스레드가 스레드를 생성하는 상황 1 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. 스레드가 스레드를 생성하는 상황</h3>\n<p>간선정보에 포함된 s 값은 간선이 만들어진 코드섹션을 의미한다. 만약에 먼저 만들어진 간선의 코드섹션이 뒤에 만들어진 간선보다 앞에 있다면 두 간선은 병렬적으로 처리되면서 만들어진 것이 아니라 순차적으로 처리된 코드에서 만들어졌음을 의미한다. 따라서 이런 경우에는 false positive 상황으로 판단하게 된다.</p>","frontmatter":{"title":"[운영체제] 교착상태를 해결하는 방법들","date":"May 28, 2020"}}},"pageContext":{"slug":"/Operating-Systems/2020-05-28-운영체제-데드락해결안/","previous":{"fields":{"slug":"/Operating-Systems/2020-05-28-운영체제-데드락조건/"},"frontmatter":{"title":"[운영체제] 교착상태의 발생조건(Necessary Conditions of Deadlock)","category":"Operating-Systems","draft":false}},"next":{"fields":{"slug":"/Algorithm-Analysis/2020-05-29-알고리즘-Floyd-Warshall/"},"frontmatter":{"title":"[알고리즘 정리] 플로이드-워셜 알고리즘(Floyd-Warshall Algorithm)","category":"Algorithm-Analysis","draft":false}}}},"staticQueryHashes":["2486386679","3128451518"]}