<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>passion_man.log</title>
        <link>https://velog.io/</link>
        <description>데이터사이언스와 자연어처리를 공부하고 있습니다. </description>
        <lastBuildDate>Tue, 07 Jun 2022 06:39:54 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>passion_man.log</title>
            <url>https://velog.velcdn.com/images/passion_man/profile/b0ec8b99-60f7-4a5e-91dc-3ca5ce91eac5/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. passion_man.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/passion_man" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[텍스트 마이닝] 13. Word Senses]]></title>
            <link>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-13.-Word-Senses</link>
            <guid>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-13.-Word-Senses</guid>
            <pubDate>Tue, 07 Jun 2022 06:39:54 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/passion_man/post/5d733636-ca27-4d96-9b59-9d131c09736a/image.png" alt="">
=&gt; bad 는 좋은 의미로 쓰일 수도 있고 나쁜 의미로 쓰일 수도 있다.
여러 의미를 가지는 단어 중에 어떤 뜻을 선택할 것인가? -&gt; Word Sense 로 파악</p>
<h1 id="word-senses">Word senses</h1>
<p><img src="https://velog.velcdn.com/images/passion_man/post/f9985d8f-88e4-4421-a818-69b31ef02097/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/63db6f0d-1170-4ed5-8477-244d78b0b0e9/image.png" alt="">
=&gt; serve 의 여러 가지 의미 중에 무슨 의미일까? -&gt; word sense 로 파악</p>
<h1 id="relationship-between-senses">Relationship between senses</h1>
<ul>
<li><p>Symomymy/antonymy (동의성/반의성)</p>
</li>
<li><p>Hypernymy (의미적 포함관계)</p>
</li>
<li><p>Metonymy (어떤 특정 단어로 전체 지칭하는 경우)</p>
</li>
<li><p>Meronymy (물리적 포함관계)</p>
</li>
<li><p>상위-하위 개념일 때, 상위개념이 하위개념을 포함 
ex) bihike(상위) 와 car(하위), bike(하위)</p>
</li>
<li><p>전체-부분 관계일 때 
ex) car(전체) 와 wheel(부분), window(부분)</p>
</li>
</ul>
<h2 id="synonym">Synonym</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/227cdccc-197e-48d5-bd9a-177871caf041/image.png" alt=""></p>
<p>=&gt; word sense로 big, large 중에 뭐 고를래? </p>
<ul>
<li>Synonymy 는 cosine similarity 가 비슷
<img src="https://velog.velcdn.com/images/passion_man/post/6a01b722-d7c2-402b-a64f-560f56e2baad/image.png" alt=""></li>
</ul>
<h2 id="antonymy">Antonymy</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/803f38e5-a1d5-42dc-851d-2d5cf93aa8f4/image.png" alt="">
=&gt; word sense로 long, short 중에 뭐 고를래?</p>
<h2 id="hyponymy">Hyponymy</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/bb328816-c5aa-42a7-b00d-237d904b02c1/image.png" alt=""></p>
<h2 id="meronymy">Meronymy</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/c4b86497-d487-4513-820a-c5b49ef8fe2f/image.png" alt=""></p>
<h1 id="dataset">Dataset</h1>
<h2 id="wordnet">WordNet</h2>
<ul>
<li>언어학자들이 명사/형용사/동사 .. 등 전부 다 분석해놓음</li>
<li>Lexical database for nouns, verbs and adjectives/adverbs</li>
<li>Each word sense is arranged in a synset and each synset is related to others in terms of their sense relations </li>
</ul>
<h3 id="relations--word-와-word의-관계를-본다">Relations : word 와 word의 관계를 본다</h3>
<p>![]<img src="https://velog.velcdn.com/images/passion_man/post/b2ec1aa0-c6ec-436f-bdb5-d6dc905f4473/image.png" alt="">
(<a href="https://velog.velcdn.com/images/passion_man/post/5d6461de-02c3-4c4c-8354-f76dcad3d028/image.png">https://velog.velcdn.com/images/passion_man/post/5d6461de-02c3-4c4c-8354-f76dcad3d028/image.png</a>)</p>
<h3 id="synsets--synymy-기반의-data-word-sense">Synsets : synymy 기반의 data word-sense</h3>
<p><img src="https://velog.velcdn.com/images/passion_man/post/ff761cd1-73d2-4d0f-9f14-23d29626b71d/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/eb9a1353-5cfa-4907-8f61-3867a5fc8b3d/image.png" alt=""></p>
<p>-&gt; 위로 올라갈 수록 상위개념</p>
<h2 id="wordnet-1">WordNet</h2>
<ul>
<li>WordNet encodes human-judged measures of similarity. Learn distributed representations of words that respect WordNet similarities -&gt; WordNet의 similarity 를 이용해서 Word vector 를 만듬</li>
</ul>
<h3 id="semcor-dataset">Semcor (dataset)</h3>
<ul>
<li>200K + words from Brown corpus tagged with WordNet senses.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/cc21b4d4-946a-428b-891d-ee8aad19f5ed/image.png" alt="">
=&gt; 위의 그림에서 숫자 1, 숫자 2는 WordNet Problem의 1번째 혹은 2번째 problem을 사용한다 라는 뜻이다. </p>
<h3 id="word-sense-disambiguation-wsd">Word Sense Disambiguation (WSD)</h3>
<p><img src="https://velog.velcdn.com/images/passion_man/post/1a2c3150-8c8f-40f6-bc03-66c6b0099773/image.png" alt=""></p>
<ul>
<li>WSD 의 여러 가지 방식
1) Dictionary methods (Lesk)
2) Supervised (machine learning)
3) Semi-supervised (Bootstrapping)</li>
</ul>
<h4 id="dictionary-methods">Dictionary methods</h4>
<ul>
<li>Predict the sense a given token that has the highest overlap between the token&#39;s context and sense&#39;s dictionary gloss -&gt; Sense1,2,3 중 classification -&gt; context와 gloss 사이에 overlap이 가장 큰 것으로 선택</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/061d8600-e78a-4f3f-a460-66b6b6843fec/image.png" alt="">
=&gt; 각 단어 word vector를 만들어서 bank1, bank2의 word vector 중 어떤 것과 가까운지 파악한다.</p>
<ul>
<li>Lest Algorithm</li>
</ul>
<h4 id="supervised-wsd">Supervised WSD</h4>
<ul>
<li>We have labeled training data; let&#39;s learn from it<ul>
<li>Decision trees <ul>
<li>Naive Bayes, long-linear classifiers, support vector machines<ul>
<li>Bidirectional LSTM </li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/15f431c5-a1a9-4d62-8985-1bbf92f2d23c/image.png" alt=""></p>
<h2 id="evaluation">Evaluation</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/e83a69b5-2bcc-45c2-845a-1ca1a1695c81/image.png" alt="">
=&gt; 맨 아랫 줄(Baseline)의 MFS는 Most Frequent Sense 로 통계적으로 가장 많이 나온 단어를 선택했을 때 결과값이다. 어떤 방식을 쓰든 이것보단 값이 높아야 한다. </p>
<blockquote>
</blockquote>
<p>if a word appears multiple times in a document, it&#39;s usually with the same sense -&gt; 언어의 특징
ex) Articles about finacial banks don&#39;t usually don&#39;t talk about river banks </p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/0322bd3e-03a9-40e5-a244-69b1d499a263/image.png" alt=""></p>
<h2 id="hyponymy-의-word-sense">hyponymy 의 word sense</h2>
<h3 id="supersense-tagging">Supersense tagging</h3>
<p><img src="https://velog.velcdn.com/images/passion_man/post/fbe83b15-841b-4219-ae84-d65ecdfebe40/image.png" alt="">
=&gt; 하위개념을 상위개념으로 Mapping 해준다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] 9. 페이징 메모리 관리]]></title>
            <link>https://velog.io/@passion_man/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-9.-%ED%8E%98%EC%9D%B4%EC%A7%95-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B4%80%EB%A6%AC</link>
            <guid>https://velog.io/@passion_man/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-9.-%ED%8E%98%EC%9D%B4%EC%A7%95-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B4%80%EB%A6%AC</guid>
            <pubDate>Fri, 03 Jun 2022 06:15:10 GMT</pubDate>
            <description><![CDATA[<h1 id="페이징-메모리-관리-개요">페이징 메모리 관리 개요</h1>
<h2 id="페이징-개념">페이징 개념</h2>
<p>1) 페이지와 프레임</p>
<ul>
<li>프로세스의 주소 공간을 0번지부터 동일한 크기의 페이지로 나눔</li>
<li>물리 메모리 역시 0번지부터 페이지 크기로 나누고, 프레임이라고 부름</li>
<li>코드, 데이터, 스택 등 프로세스의 구성 요소에 상관없이 고정 크기로 분할한 단위</li>
<li>페이지와 프레임에 번호 붙임</li>
<li>페이지의 크기<ul>
<li>주로 4KB, 운영체제마다 다르게 설정 가능 </li>
</ul>
</li>
<li>페이지 테이블<ul>
<li>각 페이지에 대해 페이지 번호와 프레임 번호를 1:1로 저장하는 테이블</li>
</ul>
</li>
</ul>
<p>2) 페이징 기법 </p>
<ul>
<li>프로세스의 주소공간과 물리 메모리를 페이지 단위로 분할하고, 프로세스의 각 페이지를 물리 메모리의 프레임에 분산 할당하고 관리하는 기법</li>
<li>프로세스의 주소공간<ul>
<li>선형적인 주소공간(0에서 시작하여 연속적인 주소공간)</li>
</ul>
</li>
<li>프로세스마다 페이지 테이블 있음</li>
<li>논리 주소의 물리 주소 변환 : MMU에 의해</li>
<li>물리 메모리의 빈 프레임 리스트 관리 필요<ul>
<li>프레임 할당 알고리즘 : 빈 프레임 중에서 선택알고리즘 필요</li>
</ul>
</li>
<li>내부 단편화 발생</li>
<li>세그먼테이션보다 우수</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/f449ca2b-ea09-4a62-9f27-18d05f2af928/image.png" alt=""></p>
<h2 id="페이징의-우수성">페이징의 우수성</h2>
<ul>
<li>용이한 구현<ul>
<li>메모리를 0번지부터 고정 크기로 단순히 분할하기 때문</li>
</ul>
</li>
<li>높은 이식성<ul>
<li>페이징 메모리 관리를 위해 CPU에 의존하는 것 없음<ul>
<li>다양한 컴퓨터 시스템에 쉽게 이식 가능</li>
</ul>
</li>
</ul>
</li>
<li>높은 융통성<ul>
<li>시스템에 따라 응용에 따라 페이지 크기 달리 설정 가능</li>
</ul>
</li>
<li>메모리 활용과 시간 오버헤드면에서 우수<ul>
<li>외부 단편화 없음<ul>
<li>내부 단편화는 발생하지만 매우 작음</li>
<li>홀 선택 알고리즘을 실행할 필요 없음</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="페이지와-페이지-테이블1">페이지와 페이지 테이블(1)</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/e7930265-d1fb-443b-bc55-10e886589a46/image.png" alt=""></p>
<p>[설명]</p>
<ul>
<li>4GB의 주소 공간을 가지는 프로세스</li>
<li>페이지 크기 4KB</li>
<li>프로세스<ul>
<li>코드 : 페이지0 ~ 페이지2에 걸쳐 있음<ul>
<li>데이터 페이지2 ~ 페이지3에 걸쳐 있음</li>
<li>힙 : 페이지3 ~ 페이지4에 걸쳐 있음</li>
<li>스택 : 사용자 공간의 맨 마지막 페이지에 할당, 1페이지 사용</li>
</ul>
</li>
</ul>
</li>
<li>현재 프로세스는 6개의 페이지를 사용하고 있음<ul>
<li>프로세스의 크기 : 6 x 4KB = 24KB</li>
</ul>
</li>
<li>페이지 테이블<ul>
<li>페이지 테이블은 주소공간의 모든 페이지를 나타낼 수 있는 항목을 포함<ul>
<li>현재 6개의 항목만 사용. 대부분의 항목은 비어 있음</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="페이지와-페이지-테이블2">페이지와 페이지 테이블(2)</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/38f9b9a0-790c-4dd0-b776-2a5449213447/image.png" alt=""></p>
<p>[설명]</p>
<p>1) 프로세스가 동적 할당 받을 때</p>
<pre><code>char *p = (char*)malloc(200); // 프로세스의 힙 영역에서 200 바이트 동적 할당</code></pre><ul>
<li>200바이트 할당 요청<ul>
<li>1페이지 (4KB) 할당<ul>
<li>논리 페이지 5할당, 물리 프레임 2할당
1) 페이지 5의 논리 주소 : 5<em>4KB = 20KB = 20</em>1024 =20480번지
2) 프레임 2의 물리 주소 : 2*4KB = 8192번지</li>
<li>malloc(200)은 페이지 번호 5의 논리 주소 20480을 리턴</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code>*p = &#39;a&#39;;</code></pre><ul>
<li><p>프로세스 내에서 20480번지에 &#39;a&#39;를 저장하는 코드</p>
<ul>
<li>논리 주소 20480이 MMU에 의해 물리 주소 8192로 바뀌어<ul>
<li>물리 메모리 8192 번지에 &#39;a&#39; 저장<pre><code>free(p);</code></pre></li>
</ul>
</li>
</ul>
</li>
<li><p>20480번지에서 할당 받은 200바이트 반환</p>
<ul>
<li>반환 후 페이지 5 전체가 비게 되므로, 페이지 5와 프레임 2가 모두 반환</li>
</ul>
</li>
</ul>
<h2 id="페이지와-페이지-테이블3">페이지와 페이지 테이블(3)</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/fd4ff784-a415-4a87-a638-ab4b0ab54e22/image.png" alt=""></p>
<p>[설명]</p>
<ul>
<li>프로세스가 시스템 호출을 실행할 때<ul>
<li>커널 공간의 페이지 k에 담긴 커널 코드 실행<ul>
<li>커널 코드 역시 논리 주소로 되어 있음</li>
<li>현재 프로세스 테이블에서 페이지 k의 물리 프레임 780090을 알아내고 물리 프레임 780090에 적재된 커널 코드 실행</li>
</ul>
</li>
</ul>
</li>
</ul>
<blockquote>
<p>[중요사항]</p>
</blockquote>
<ul>
<li>커널 코드도 논리 주소로 되어 있으며, 시스템 호출을 통해 커널 코드가 실행될 때 현재 프로세스의 페이지 테이블을 이용하여 물리 주소로 변환된다. </li>
</ul>
<h2 id="페이지와-페이지-테이블에-대한-정리">페이지와 페이지 테이블에 대한 정리</h2>
<p>** 32비트 CPU에서, 페이지 크기가 4KB인 경우</p>
<ol>
<li>물리 메모리의 최대 크기는?</li>
</ol>
<ul>
<li>물리 주소의 범위는 0 ~ 2<sup>32</sup> -1</li>
<li>한 주소 당 한 바이트 크기이므로 물리 메모리의 최대 크기는 2<sup>32</sup> = 4GB</li>
</ul>
<ol start="2">
<li>프로세스의 주소 공간의 크기?</li>
</ol>
<ul>
<li>2<sup>32</sup> 개의 주소들이므로, 총 4GB</li>
<li>물리 메모리는 1GB, 2GB, 4GB 등 다양하게 설치될 수 있지만, 프로세스의 주소 공간은 물리 메모리 크기에 상관없이 4GB</li>
</ul>
<ol start="3">
<li>한 프로세스는 최대 몇 개의 페이지로 구성되는가?</li>
</ol>
<ul>
<li>4GB/4KB = 2<sup>32</sup>/2<sup>12</sup> = 2<sup>20</sup>개 = 1M개 = 약 100만 개</li>
</ul>
<ol start="4">
<li>프로세스 당 하나의 페이지 테이블이 있다. 페이지 테이블의 크기는?</li>
</ol>
<ul>
<li>페이지 테이블 항목 크기가 32비트(4B)라면</li>
<li>4바이트*2<sup>20</sup> = 2<sup>22</sup>바이트 = 4MB</li>
</ul>
<ol start="5">
<li>응용프로그램이 하나의 프로세스라고 할 때, 응용프로그램의 최대 크기, 즉 개발자가 작성할 수 있는 프로그램의 최대 크기는?</li>
</ol>
<ul>
<li>운영체제가 설정한 사용자 공간의 크기</li>
</ul>
<ol start="6">
<li>페이지 테이블 모양은</li>
</ol>
<ul>
<li>대부분이 비어 있는 희소 테이블</li>
</ul>
<ol start="7">
<li>페이지 테이블은 어디에 존재하는가?</li>
</ol>
<ul>
<li>메모리에 저장</li>
</ul>
<ol start="8">
<li>커널 코드가 논리 주소로 되어 있는가 물리 주소로 되어 있는가?</li>
</ol>
<ul>
<li>커널 코드 역시 논리 주소로 되어 있음. 그러므로 커널 코드가 실행될 때 역시 물리 주소로 바뀌어야 하는데 이때 사용되는 페이지 테이블은 현재 프로세스의 페이지 테이블이 사용됨</li>
</ul>
<h2 id="페이징에서의-단편화">페이징에서의 단편화</h2>
<ul>
<li>외부 단편화 발생 없음</li>
<li>내부 단편화 발생<ul>
<li>코드와 데이터가 주소 공간에서 연속되어 있다.<ul>
<li>스택이나 힙에 생성하는 페이지는 계속 변하므로 단편화 계산에서 제외한다면</li>
<li>프로세스의 마지막 페이지에만 단편화 발생</li>
<li>단편화의 평균 크기 = 페이지의 1/2 크기</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="페이징-개념-확인">페이징 개념 확인</h2>
<p>** 32비트 CPU에서, 페이지의 크기가 2KB, 현재 설치된 메모리 1GB, 프로세스 A는 사용자 공간에서 54321바이트를 차지한다고 할 때</p>
<ol>
<li>물리 메모리의 프레임 크기는? </li>
</ol>
<ul>
<li>2KB로 페이지 크기와 동일</li>
</ul>
<ol start="2">
<li>물리 메모리의 프레임 개수는?</li>
</ol>
<ul>
<li>물리 메모리를 프레임 크기로 나누면 됨. 1GB/2KB = 2<sup>30</sup>/2<sup>11</sup> = 2<sup>19</sup>개, 약 50만 개</li>
</ul>
<ol start="3">
<li>프로세스 A의 주소 공간 크기와 페이지의 개수는?</li>
</ol>
<ul>
<li>프로세스의 주소 공간 크기는 2<sup>32</sup> = 4GB. 페이지의 개수 = 2<sup>32</sup>/2<sup>11</sup>=2<sup>21</sup>개 = 2M개 = 약 2백만 개</li>
</ul>
<ol start="4">
<li>프로세스 A는 몇 개의 페이지로 구성되는가? 프로세스 A를 모두 적재하기 위한 물리 프레임의 개수는?</li>
</ol>
<ul>
<li>프로세스 A의 실제 크기가 54321 바이트이므로, 2KB(2048)로 나누면 26.5이므로 27개 페이지(프레임)</li>
</ul>
<ol start="5">
<li>페이지 테이블 항목의 크기가 4바이트라고 할 때, 프로세스 A의 페이지 테이블의 크기는?</li>
</ol>
<ul>
<li>테이블 항목이 총 2<sup>21</sup>개이므로 2<sup>21</sup>*4바이트 = 2<sup>23</sup>바이트 = 8MB</li>
</ul>
<ol start="6">
<li>페이징에서 단편화 메모리의 평균 크기는?</li>
</ol>
<ul>
<li>프로세스의 코드와 데이터 연속되어 있으므로, 마지막 페이지에만 단편화가 생긴다. 평균은 페이지의 반이므로 1KB</li>
</ul>
<ol start="7">
<li>페이지의 크기와 단편화의 관계는?</li>
</ol>
<ul>
<li>페이지의 크기가 크면 단편화도 커진다. 하지만 극히 미미하다.</li>
</ul>
<ol start="8">
<li>페이지의 크기와 페이지 테이블의 크기 관계는?</li>
</ol>
<ul>
<li>페이지 크기가 크면 페이지 개수가 작아지고 페이지 테이블의 크기도 작아진다. </li>
</ul>
<h1 id="페이징의-주소-체계">페이징의 주소 체계</h1>
<h2 id="페이징의-논리-주소">페이징의 논리 주소</h2>
<p> 논리 주소 구성</p>
<ul>
<li><p>[페이지 번호(p), 옵셋(offset)]</p>
<ul>
<li>페이지 크기가 4KB(=2<sup>12</sup>)라면, 페이지 내 각 바이트 주소 12비트<ul>
<li>옵셋 크기는 12비트</li>
</ul>
</li>
</ul>
</li>
<li><p>32비트 논리 주소 체계에서,</p>
<ul>
<li>상위 20비트는 페이지 번호<ul>
<li>하위 12비트는 옵셋</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/fd9bf063-7af2-418e-acc2-0c5d8af8e6c9/image.png" alt=""></p>
<h2 id="논리-주소의-물리-주소-변환-개념">논리 주소의 물리 주소 변환 개념</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/732c3e1e-f7bd-4596-b1af-c5e8c0a65ae3/image.png" alt=""></p>
<h2 id="페이징-구현">페이징 구현</h2>
<ol>
<li>하드웨어 지원</li>
</ol>
<ul>
<li>CPU의 지원<ul>
<li>CPU에 페이지 테이블이 있는 메모리 주소를 가진 레지스터 필요<ul>
<li>Page Table Base Register (PTBR)</li>
<li>이 레지스터는 운영체제에 의해 제어</li>
</ul>
</li>
</ul>
</li>
<li>MMU 장치<ul>
<li>논리 주소의 물리 주소 변환<ul>
<li>페이지 테이블을 저장하고 검색하는 빠른 캐시 포함</li>
<li>메모리 보호 - 페이지 번호가 페이지 테이블에 있는지, 옵셋이 페이지의 범위를 넘어가는지 확인</li>
</ul>
</li>
</ul>
</li>
</ul>
<ol start="2">
<li>운영체제 지원</li>
</ol>
<ul>
<li>프레임의 동적할당/반환 및 페이지 테이블 관리 기능 구현<ul>
<li>프로세스의 생성/소멸에 따라 동적으로 프레임 할당/반환<ul>
<li>물리 메모리에 할당된 페이지 테이블과 빈 프레임 리스트 생성 관리 유지</li>
<li>컨텍스트 스위칭 때, PCB로부터 페이지 테이블의 물리주소를 CPU의 PTBR 레지스터에 로딩</li>
</ul>
</li>
</ul>
</li>
</ul>
<h1 id="페이지-테이블의-문제점과-tlb">페이지 테이블의 문제점과 TLB</h1>
<p>2가지 문제점</p>
<ol>
<li>1번에 메모리 액세스를 위한 2번의 물리 메모리 액세스</li>
</ol>
<ul>
<li>페이지 테이블은 몇 MB의 크기로 메모리에 저ㅏㅇ</li>
<li>CPU가 메모리를 액세스할 때마다, 2번의 물리 메모리 액세스 -&gt; 실행 속도 저하</li>
<li>TLB 사용으로 해결</li>
</ul>
<ol start="2">
<li>페이지 테이블의 낭비</li>
</ol>
<ul>
<li>프로세스의 실제 크기는 매우 작기 때문에</li>
<li>대부분의 페이지 테이블 항목이 비어 있는 문제</li>
<li>2레벨 페이지 테이블 등 방법으로 해결
<img src="https://velog.velcdn.com/images/passion_man/post/601888fd-e998-4440-a136-6684d695f574/image.png" alt=""></li>
</ul>
<h2 id="c프로그램이-실행될-때-메모리-액세스-과정-분석">C프로그램이 실행될 때 메모리 액세스 과정 분석</h2>
<pre><code>int n[100]; 
int sum = 0;

for(int i = 0; i&lt; 100; i++)
    sum += n[i];</code></pre><blockquote>
</blockquote>
<ul>
<li>32비트 CPU, 페이지는 4KB</li>
<li>배열 n[100]의 논리 주소는 0x2000(페이지2)부터 시작</li>
<li>배열 n[100]의 물리 주소는 0x7000(프레임7)부터 시작</li>
<li>배열 n[100]의 크기는 400바이트이며 페이지2에 모두 들어 있음</li>
<li>페이지 테이블은 물리 메모리 0xA000번지부터 시작</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/095cc2a5-4857-409f-a461-aa1ce2fcf4ae/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/addde65f-a126-4865-ae12-629c47c670eb/image.png" alt=""></p>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/passion_man/post/90f38be5-1e0f-4d7f-8aa4-7ebb609f9b06/image.png" alt=""></p>
<h2 id="tlb를-이용한-2번의-물리-메모리-액세스-문제-해결">TLB를 이용한 2번의 물리 메모리 액세스 문제 해결</h2>
<p>1) 문제 해결 실마리</p>
<ul>
<li>논리 주소를 물리 주소로 바꾸는 과정에서 페이지 테이블을 읽어오는 시간을 없애거나 줄이는 기법</li>
</ul>
<p>2) TLB(Tranlation Look-aside Buffer) 사용</p>
<ul>
<li><p>주소 변환 캐시(address translation cache) 로 불림</p>
</li>
<li><blockquote>
<p>최근에 접근한 &#39;페이지와 프레임 번호&#39;의 쌍을 항목으로 저장하는 캐시 메모리</p>
</blockquote>
</li>
<li><p>위치</p>
</li>
<li><blockquote>
<p>현대 컴퓨터에서는 MMU내에 존재</p>
</blockquote>
</li>
<li><p>TLB캐시의 구조와 특징</p>
</li>
<li><blockquote>
<p>[페이지 번호 p, 프레임 번호 f]를 항목으로 저장</p>
</blockquote>
</li>
<li><blockquote>
<p>페이지 번호를 받아 전체 캐시를 동시에 고속 검색, 프레임 번호 출력, content-addressable memory, associative memory라고 불림(연관 메모리)</p>
</blockquote>
</li>
<li><blockquote>
<p>고가, 크기 작음(64~1024개의 항목 정도 저장)</p>
</blockquote>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/3caea96a-7d10-43f1-9f98-a55e63d9b489/image.png" alt=""></p>
<h2 id="tlb를-활용한-메모리-액세스">TLB를 활용한 메모리 액세스</h2>
<ol>
<li>CPU로부터 논리 주소 발생</li>
<li>논리 주소의 페이지 번호가 TLB로 전달</li>
<li>페이지 번호와 TLB 내 모든 항목 동시에 비교</li>
</ol>
<ul>
<li>TLB에 페이지가 있는 경우, TLB hit<ul>
<li>TLB에서 출력되는 프레임 번호와 offset 값으로 물리 주소 완성</li>
</ul>
</li>
<li>TLB에 페이지가 없는 경우, TLB miss<ul>
<li>TLB는 miss 신호 발생<ul>
<li>MMU는 페이지 테이블로부터 프레임 번호를 읽어와서 물리 주소 완성</li>
<li>미스한 페이지의 [페이지번호, 프레임번호] 항목을 TLB에 삽입</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/c99158c8-df54-46d2-9496-82819ad31286/image.png" alt=""></p>
<h2 id="tlb가-있는-경우-c프로그램-실행-과정-분석">TLB가 있는 경우 C프로그램 실행 과정 분석</h2>
<pre><code>int n[100]; 
int sum = 0;

for(int i = 0; i&lt; 100; i++)
    sum += n[i];</code></pre><p><img src="https://velog.velcdn.com/images/passion_man/post/bf75456f-ab79-40d5-a017-668158428140/image.png" alt=""></p>
<h2 id="배열이-2개의-페이지에-걸쳐-있는-경우-tlb-활용-사례">배열이 2개의 페이지에 걸쳐 있는 경우 TLB 활용 사례</h2>
<pre><code>int n[100]; 
int sum = 0;

for(int i = 0; i&lt; 100; i++)
    sum += n[i];</code></pre><blockquote>
</blockquote>
<ul>
<li>배열 n[2000]의 논리 주소는 0x2000부터 시작하여 페이지 2,3에 걸쳐 존재</li>
<li>배열 n[2000]의 물리 주소는 0x7000부터 시작하여 프레임 7과 9에 나누어 할당</li>
<li>페이지 테이블이 메모리 0xA000번지에서 시작</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/5d73c9ad-d84d-4e91-8149-629157605792/image.png" alt=""></p>
<h2 id="tlb로-부터-얻는-교훈">TLB로 부터 얻는 교훈</h2>
<p>1) TLB와 참조의 지역성</p>
<ul>
<li>TLB는 참조의 지역성으로 인해 효과적인 전략임</li>
<li>TLB를 사용하면, 순차 메모리 액세스 시에 실행 속도 빠름<ul>
<li>TLB 히트가 계속됨(메모리의 페이지 테이블 액세스할 필요 없음)</li>
</ul>
</li>
<li>TLB를 사용하면, 랜덤 메모리 액세스나 반복이 없는 경우 실행 속도 느림<ul>
<li>TLB 미스 자주 발생<ul>
<li>TLB의 항목 교체(TLB 항목의 개수 제한되기 때문)</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>2) TLB의 성능</p>
<ul>
<li>TLB 히트율 높이기 -&gt; TLB 항목 늘이기(비용과의 trade-off)</li>
<li>페이지 크기<ul>
<li>페이지가 클수록 TLB 히트 증가 -&gt; 실행 성능 향상<ul>
<li>페이지가 클수록 내부 단편화 증가 -&gt; 메모리 낭비</li>
<li>이 둘 사이에는 trade-off 존재, 선택의 문제</li>
<li>페이지가 커지는 추세 : 디스크 입출력의 성능 향상을 위해</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>3) TLB reach - TLB 성능 지수(figure of merit)</p>
<ul>
<li>TLB 도달 범위</li>
<li>TLB가 채워졌을 때, 미스없이 작동하는 메모리 액세스 범위</li>
<li>TLB 항목 수 X 페이지 크기</li>
</ul>
<h2 id="tlb를-고려한-컨텍스트-스위칭-과정-재정리">TLB를 고려한 컨텍스트 스위칭 과정 재정리</h2>
<ol>
<li>CPU의 모든 레지스터를 PCB에 저장</li>
<li>PCB에 있는 프로세스의 페이지 테이블의 주소를 MMU(CPU)의 Page Table Base Register(PTBR)로 로딩</li>
</ol>
<ul>
<li>TLB 미스 시에 페이지 테이블을 액세스하여 물리 주소를 알아내고</li>
<li>TLB로 페이지 테이블 엔트리 이동하기 위함</li>
</ul>
<ol start="3">
<li>TLB 내용 모두 지우기</li>
</ol>
<ul>
<li>새로운 프로세스의 실행이 시작되면 TLB 미스가 발생하고 TLB에 항목이 채워지기 시작함</li>
<li>큰 비용 대가</li>
</ul>
<ol start="4">
<li>새 프로세스 컨텍스트(CPU레지스터)를 PCB에서 CPU로 로딩</li>
</ol>
<h1 id="페이지-테이블의-메모리-낭비-문제-해결">페이지 테이블의 메모리 낭비 문제 해결</h1>
<h2 id="페이지-테이블의-메모리-낭비">페이지 테이블의 메모리 낭비</h2>
<p>1) 32비트 CPU 환경에서 프로세스 당 페이지 테이블 크기</p>
<ul>
<li>프로세스의 주소 공간<ul>
<li>4GB/4KB = 2<sup>32</sup>/2<sup>12</sup> = 2<sup>20</sup> = 약 100만 개의 페이지로 구성</li>
</ul>
</li>
<li>프로세스 당 페이지 테이블의 크기<ul>
<li>한 항목이 4바이트이면 2<sup>20</sup> x 4바이트 - 4MB</li>
</ul>
</li>
</ul>
<p>2) 10MB의 메모리를 사용하는 프로세스가 있다고 하면</p>
<ul>
<li><p>실제 활용되는 페이지 테이블 항목 수</p>
<ul>
<li>10MB/4KB = 10 x 2<sup>20</sup>/2<sup>12</sup> = 10 x 2<sup>8</sup> = 2560개</li>
</ul>
</li>
<li><p>실제 활용되는 페이지 테이블 비율</p>
<ul>
<li>10 x 2<sup>8</sup>/2<sup>20</sup> = 10/2<sup>12</sup> = 0.0024<ul>
<li>매우 낮음</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="페이지-테이블-낭비-문제의-해결책">페이지 테이블 낭비 문제의 해결책</h2>
<ol>
<li>역 페이지 테이블(inverted page table, IPT)</li>
</ol>
<ul>
<li>시스템에 하나의 역 페이지 테이블만 둠<ul>
<li>역 페이지 테이블 항목의 수 = 물리 메모리의 프레임 개수</li>
</ul>
</li>
<li>역 페이지 테이블 항목<ul>
<li>[프로세스번호(pid), 페이지 번호(p)]</li>
</ul>
</li>
<li>역 페이지 테이블의 인덱스<ul>
<li>프레임 번호</li>
</ul>
</li>
<li>역 페이지 테이블을 사용한 주소 변환<ul>
<li>논리 주소에서 (프로세스번호, 페이지 번호)로 역 페이지 테이블 검색<ul>
<li>일치하는 항목을 발견하면 항목 번호가 바로 프레임 번호임</li>
<li>프레임 번호와 옵셋을 연결하면 물리주소</li>
</ul>
</li>
</ul>
</li>
</ul>
<ol start="2">
<li>멀티 레벨 페이지 테이블</li>
</ol>
<ul>
<li>페이지 테이블은 하나의 페이지에 넣고 페이지 테이블을 가리키는 페이지 구성</li>
<li>사용 중인 페이지들에 대해서만 페이지 테이블 구성</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/ecc5c553-deba-4dde-b450-b4b5cbbe0920/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/0fb1aebe-230c-427a-9b55-2bd5b9142205/image.png" alt=""></p>
<h2 id="역-페이지-테이블의-크기">역 페이지 테이블의 크기</h2>
<p>1) 역 페이지 테이블의 개수</p>
<ul>
<li>시스템에 1개 존재
2) 역 페이지 테이블의 크기</li>
<li>역 페이지 테이블의 항목 크기<ul>
<li>프로세스 번호와 페이지 번호로 구성<ul>
<li>프로세스 번호와 페이지 번호가 각각 4바이트라면, 항목 크기는 8바이트</li>
</ul>
</li>
</ul>
</li>
<li>역 페이지 테이블의 항목 수 = 물리 메모리 크기/프레임 크기<ul>
<li>예) 물리 메모리가 4GB, 프레임 크기 4KB이면
역 페이지 테이블 항목 수 = 4GB/4KB = 2<sup>20</sup> 개 = 약 100만개</li>
</ul>
</li>
<li>역 페이지 테이블의 크기는 컴퓨터에 설치된 물리 메모리 크기에 따라 달라짐<ul>
<li>물리 메모리는 컴퓨터마다 서로 다르게 설치될 수 있음<ul>
<li>예) 물리 메모리가 4GB, 프레임 크기가 4KB, 한 항목의 크기가 8바이트라면 역 페이지 테이블의 크기는 = 2<sup>20</sup> 개 항목 x 8 바이트 = 8MB</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>3) 기존 페이지 테이블과 비교</p>
<ul>
<li><p>예) 10개의 프로세스가 실행 중일 때, 
기존 페이지 테이블 = 4MB x 10개 = 40MB 크기
역 페이지 테이블 = 8MB (기존의 1/5 수준)</p>
</li>
<li><p>역 페이지 테이블 구현</p>
<ul>
<li>Linear inverted page table<ul>
<li>Hashed inverted page table - PID와 p를 키로 해싱하여 단번에 일치하는 항목을 찾고 물리 주소로 변환한다. - PowerpC, UltraSPAC</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="멀티레벨-페이지-테이블">멀티레벨 페이지 테이블</h2>
<p>1) 멀티레벨 페이지 테이블 개념</p>
<ul>
<li><p>현재 사용 중인 페이지들에 대해서만 페이지 테이블 만드는 방식</p>
<ul>
<li>기존 페이지 테이블의 낭비를 줄임</li>
</ul>
</li>
<li><p>페이지 테이블을 수십~ 수백 개의 작은 페이지 테이블로 나누고 이들을 여러 레벨로 구성</p>
</li>
</ul>
<p>2) 2-레벨로 멀티레벨 페이지 테이블을 구성하는 경우</p>
<ul>
<li>논리 주소 구성<ul>
<li>[페이지 디렉터리 인덱스, 페이지 테이블 인덱스, 옵셋]<ul>
<li>페이지 크기 4KB<ul>
<li>논리 주소의 하위 12비트 : 페이지 내 옵셋 주소</li>
</ul>
</li>
<li>논리 주소의 상위 20비트 : 페이지 디렉터리 인덱스와 페이지 테이블 인덱스</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/2483a58a-9556-40e4-b718-b428018c5bc9/image.png" alt=""></p>
<h2 id="1024개의-페이지마다-1개의-페이지-테이블-사용">1024개의 페이지마다 1개의 페이지 테이블 사용</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/c4fb4d66-c50f-46f4-ac53-b7b5bb3f12d1/image.png" alt=""></p>
<h2 id="2-레벨-페이지-테이블--페이지-디렉터리와-페이지-테이블로-구성">2-레벨 페이지 테이블 : 페이지 디렉터리와 페이지 테이블로 구성</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/f0b3639d-a0b9-414d-8e1f-4ef611b93266/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/95c48188-3bd6-49b9-b2fa-b88f8f0d11da/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/eec4a057-b7f5-4b8e-9482-674fdab379b0/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/0fde4c65-4af0-4114-ad74-129cc1529eea/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/b0cb2111-4322-4095-bebf-7cdb57704222/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/9d7eb16d-7bb1-4868-aa36-de456b760338/image.png" alt=""></p>
<p>이 사례에서 페이지 테이블의 크기 = 
페이지 데렉터리 1개(4KB) + 3개의 페이지 테이블(12KB)
= 16KB</p>
<p>페이지 테이블의 크기가 대폭 감소됨</p>
<h2 id="2-레벨-페이지-테이블의-크기">2-레벨 페이지 테이블의 크기</h2>
<p>1) 2-레벨 페이지 테이블의 최대 메모리 소모량</p>
<ul>
<li>페이지 디렉터리 1개 + 최대 1024개의 페이지 테이블</li>
<li>= 4KB + 1024* 4KB = 4KB + 4MB</li>
<li>하지만, 일반적으로 프로세스는 1024개의 페이지 테이블을 모두 사용하지 않음</li>
</ul>
<p>2) 사례1 - 프로세스가 1000개의 페이지로 구성</p>
<ul>
<li>1000개의 페이지는 1개의 페이지 테이블에 의해 매핑 가능</li>
<li>메모리 소모량<ul>
<li>1개의 페이지 디렉터리와 1개와 1개의 페이지 테이블<ul>
<li>= 4KB + 4KB = 8KB</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>3) 사례2 - 프로세스가 400MB 크기인 경우</p>
<ul>
<li>프로세스의 페이지 개수 = 400MB/4KB = 100x1024개<ul>
<li>100개의 페이지 테이블 필요</li>
</ul>
</li>
<li>메모리 소모량<ul>
<li>1개의 페이지 디렉터리와 100개의 페이지 테이블<ul>
<li>= 4KB = 100 x 4KB = 404KB</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>4) 결론</p>
<ul>
<li>기존 페이지 테이블의 경우 프로세스 크기에 관계없이 프로세스 당 4MB가 소모</li>
<li>2-레벨 페이지 테이블의 경우 페이지 테이블로 인한 메모리 소모를 확연히 줄일 수 있다.</li>
</ul>
<p>이 글이 문제가 된다면 삭제하겠습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] 8. 메모리 관리]]></title>
            <link>https://velog.io/@passion_man/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-8.-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B4%80%EB%A6%AC</link>
            <guid>https://velog.io/@passion_man/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-8.-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B4%80%EB%A6%AC</guid>
            <pubDate>Mon, 30 May 2022 04:46:35 GMT</pubDate>
            <description><![CDATA[<h1 id="메모리-계층-구조와-메모리-관리-핵심">메모리 계층 구조와 메모리 관리 핵심</h1>
<h2 id="메모리-계층-구조">메모리 계층 구조</h2>
<ul>
<li><p>메모리는 컴퓨터 시스템 여러 곳에 계층적으로 존재</p>
<ul>
<li>CPU 레지스터 - CPU 캐시 - 메인 메모리 - 보조기억장치<ul>
<li>CPU 레지스터에서 보조기억장치로 갈수록 
1) 용량 증가
2) 가격 저렴
3) 속도 저하</li>
<li>메모리 계층 구조의 중심 - 메인 메모리</li>
</ul>
</li>
</ul>
</li>
<li><p>메모리 계층화의 목적</p>
<ul>
<li>빠른 프로그램 실행을 위해 CPU의 메모리 엑세스 시간을 줄이기 위함
<img src="https://velog.velcdn.com/images/passion_man/post/1f0ac78f-8ee0-47eb-95ba-91ab089efcc0/image.png" alt=""></li>
</ul>
</li>
</ul>
<h2 id="메모리-계층구조의-특성">메모리 계층구조의 특성</h2>
<table>
<thead>
<tr>
<th></th>
<th>CPU 레지스터</th>
<th>L1/L2 캐시</th>
<th>L3 캐시</th>
<th>메인 메모리</th>
<th>보조기억장치</th>
</tr>
</thead>
<tbody><tr>
<td>용도</td>
<td>몇 개의 명령과 데이터 저장</td>
<td>한 코어에서 실행되는 명령과 데이터 저장</td>
<td>멀티 코어들에 의해 공유. 명령과 데이터 저장</td>
<td>실행 중인 전체 프로세스들의 코드와 데이터, 입출력 중인 파일 블록들 저장</td>
<td>파일이나 데이터베이스, 그리고 메모리에 적재된 프로세스의 코드와 데이터의 일시저장</td>
</tr>
<tr>
<td>용량</td>
<td>바이트 단위. 8~30개 정도. 1KB 미만</td>
<td>KB 단위 (Core i7의 경우 32KB/256KB)</td>
<td>MB 단위(Core i7의 경우 8MB)</td>
<td>GB 단위 (최근 PC의 경우 최소 8GB 이상)</td>
<td>TB 단위</td>
</tr>
<tr>
<td>타입</td>
<td></td>
<td>SRAM (static RAM)</td>
<td>SRAM (static RAM)</td>
<td>DRAM (Dynamic RAM)</td>
<td>마그네틱 필드나 플래시 메모리</td>
</tr>
<tr>
<td>속도</td>
<td>&lt;1ns</td>
<td>&lt;5ns</td>
<td>&lt;5ns</td>
<td>&lt;50ns</td>
<td>&lt;20ms</td>
</tr>
<tr>
<td>가격</td>
<td></td>
<td>고가</td>
<td>고가</td>
<td>보통</td>
<td>저가</td>
</tr>
<tr>
<td>휘발성</td>
<td>휘발성</td>
<td>휘발성</td>
<td>휘발성</td>
<td>휘발성</td>
<td>비휘발성</td>
</tr>
</tbody></table>
<h2 id="메모리-계층화---성능과-비용의-절충">메모리 계층화 - 성능과 비용의 절충</h2>
<p>1) 계층화 </p>
<ul>
<li>계층화 과정<ul>
<li>CPU 성능 향상 -&gt; 더 빠른 메모리 요구 -&gt; 작지만 빠른 off-chip 캐시 등장 -&gt; 더 빠른 액세스를 위해 on-chip 캐시 -&gt; 멀티 코어의 성능에 적합한 L1, L2, L3 캐시<ul>
<li>컴퓨터의 성능 향상 -&gt; 처리할 데이터도 대형화 -&gt; 저장 장치(하드 디스크)의 대형화 -&gt; 빠른 저장 장치 요구 -&gt; SSD의 등장</li>
</ul>
</li>
</ul>
</li>
<li>성능과 비용의 절충<ul>
<li>빠른 메모리일수록 고가이므로 작은 용량 사용</li>
</ul>
</li>
</ul>
<p>2) 계층화 성공 이유</p>
<ul>
<li>참조의 지역성 때문<ul>
<li>코드나 데이터, 자원 등이 아주 짧은 시간 내에 다시 사용되는 프로그램의 특성<ul>
<li>CPU는 작은 캐시 메모리에 로딩된 코드와 데이터로 한동안 실행</li>
<li>캐시를 채우는 시간의 손해보다 빠른 캐시를 이용하는 이득이 큼</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>3) 계층화의 미래</p>
<ul>
<li>현재, 메모리와 하드디스크 사이에 또 다른 형태의 메모리가 구현되고 있음
<img src="https://velog.velcdn.com/images/passion_man/post/cfbeeca0-2982-4176-8ae2-03c5cf454c74/image.png" alt=""></li>
</ul>
<h2 id="메모리-관리">메모리 관리</h2>
<p>1) 메모리의 역할</p>
<ul>
<li>메모리는 실행하고자 하는 프로그램의 코드와 데이터 적재</li>
<li>CPU는 메모리에 적재된 코드와 데이터만 처리</li>
</ul>
<p>2) 운영체제에 의해 메모리 관리가 필요한 이유</p>
<ul>
<li>메모리는 공유 자원<ul>
<li>여러 프로세스 사이에 메모리 공유</li>
<li>각 프로세스에게 물리 메모리 할당</li>
</ul>
</li>
<li>메모리 보호<ul>
<li>프로세스의 독립된 메모리 공간 보장<ul>
<li>사용자 코드로부터 커널 공간 보호</li>
</ul>
</li>
</ul>
</li>
<li>메모리 용량 한계 극복<ul>
<li>설치된 물리 메모리보다 큰 프로세스 지원 필요<ul>
<li>여러 프로세스의 메모리 합이 설치된 물리 메모리보다 큰 경우 필요</li>
</ul>
</li>
</ul>
</li>
<li>메모리 효율성 증대 <ul>
<li>가능하면 많은 개수의 프로세스를 실행시키기 위해</li>
<li>프로세스 당 최소한의 메모리 할당</li>
</ul>
</li>
</ul>
<h1 id="메모리-주소">메모리 주소</h1>
<h2 id="물리-주소와-논리-주소">물리 주소와 논리 주소</h2>
<p>1) 메모리는 오직 주소로만 접근
2) 주소의 종류</p>
<ul>
<li>물리 주소<ul>
<li>물리 메모리(RAM)에 매겨진 주소. 하드웨어에 의해 고정된 메모리 주소<ul>
<li>0에서 시작하여 연속되는 주소 체계</li>
<li>메모리는 시스템 주소 버스를 통해 물리 주소의 신호 받음</li>
</ul>
</li>
</ul>
</li>
<li>논리/가상 주소<ul>
<li>개발자나 프로세스가, 프로세스 내에서 사용하는 주소, 코드나 변수 등에 대한 주소<ul>
<li>0에서 시작하여 연속되는 주소 체계</li>
<li>CPU가 프로세스를 실행하는 동안 다루는 모든 주소는 논리 주소<ul>
<li>프로세스 내에서 매겨진 상대주소 (프로그램에서 변수 n의 주소가 100번지라면, 논리 주소가 100이고, 물리 주소를 알 수 없음)</li>
<li>컴파일러와 링커에 의해 매겨진 주소 (실행 파일 내에 만들어진 이진 프로그램의 주소들은 논리 주소로 되어 있음)</li>
</ul>
</li>
<li>사용자나 프로세스는 결코 물리 주소를 알 수 없음
3) MMU (Memory Management Unit)</li>
</ul>
</li>
</ul>
</li>
<li>논리 주소를 물리 주소로 바꾸는 하드웨어 장치<ul>
<li>CPU가 발생시킨 논리 주소는 MMU에 의해 물리 주소로 바뀌어 메모리에 도달</li>
</ul>
</li>
<li>오늘날 MMU는 CPU 안에 내장<ul>
<li>인텔이나 AMD의 x86 CPU는 80286부터 MMU를 내장<ul>
<li>MMU 덕분에 여러 프로세스가 하나의 메모리에서 실행되도록 됨<img src="https://velog.velcdn.com/images/passion_man/post/34ca3ef8-542b-487a-bc49-f8e2f23d7758/image.png" alt=""></li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="c-프로그램에서의-주소는-논리-주소인가-물리-주소인가">C 프로그램에서의 주소는 논리 주소인가 물리 주소인가?</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/a6e2f7bc-c941-4d7c-9f1a-2ef8ea3fbc7b/image.png" alt=""></p>
<blockquote>
<p>[참고]</p>
</blockquote>
<ul>
<li>ASLR (Address Space Layout Randomization)<ul>
<li>해커들의 메모리 공격에 대한 대비책<ul>
<li>주소 공간의 랜덤 배치</li>
</ul>
</li>
<li>프로세스의 주소 공간 내에서 스택이나 힙, 라이브러리 영역의 랜덤 배치</li>
<li>실행할 때마다 이들의 논리 주소가 바뀌게 하는 기법 -&gt; 실행할 때마다 함수의 지역 변수와 동적 할당 받는 메모리의 논리 주소가 바뀜</li>
<li>하지만, 코드나 전역 변수가 적재되는 데이터 영역의 논리 주소는 바뀌지 않음
<img src="https://velog.velcdn.com/images/passion_man/post/1a7867f1-16dd-4355-bce8-ec1c5999735f/image.png" alt=""></li>
</ul>
</li>
</ul>
<h1 id="물리-메모리-관리">물리 메모리 관리</h1>
<h2 id="메모리-할당">메모리 할당</h2>
<ul>
<li>운영체제가 새 프로세스를 실행 시키거나 실행 중인 프로세스가 메모리를 필요로 할 때, 물리 메모리 할당</li>
<li>프로세스의 실행은 할당된 물리 메모리에서 이루어짐<ul>
<li>프로세스의 코드, 변수, 스택, 동적 할당 공간 액세스 등 </li>
</ul>
</li>
</ul>
<h2 id="메모리-할당-기법">메모리 할당 기법</h2>
<p>1) 연속 메모리 할당</p>
<ul>
<li>프로세스별로 연속된 한 덩어리의 메모리 할당</li>
<li>고정 크기 할당<ul>
<li>메모리를 고정 크기의 파티션으로 나누고 프로세스 당 하나의 파티션 할당</li>
</ul>
</li>
<li>가변 크기 할당<ul>
<li>메모리를 가변 크기의 파티션으로 나누고 프로세스 당 하나의 파티션 할당</li>
</ul>
</li>
</ul>
<p>2) 분할 메모리 할당</p>
<ul>
<li>프로세스에게 여러 덩어리로 나누어 메모리 할당</li>
<li>고정 크기 할당<ul>
<li>고정 크기의 동일한 덩어리 메모리의 분산 할당. 대표 방법 - Segmentation 기법</li>
</ul>
</li>
<li>가변 크기 할당<ul>
<li>가변 크기의 덩어리 메모리를 분산 할당. 대표 방법 - 페이징 기법</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/9f96a10c-c21b-4f8a-8412-91912a20f3da/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/9d204f81-4d5d-48a7-8762-3d0ca0ad0210/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/f22edc68-694f-4215-835b-b55c703f6b9d/image.png" alt="">
※ 왼쪽 오른쪽 그림 위치가 바뀜</p>
<h1 id="연속-메모리-할당">연속 메모리 할당</h1>
<h2 id="연속-메모리-할당-1">연속 메모리 할당</h2>
<p>1) 각 프로세스 영역(코드와 데이터)을 연속된 메모리 공간에 배치 </p>
<ul>
<li>메모리를 한 개 이상의 파티션으로 분할하고 파티션을 할당하는 기법 </li>
<li>한 프로세스는 한 파티션으로 할당</li>
</ul>
<p>2) 연속 메모리 할당은 초기 운영체제에서 사용</p>
<ul>
<li><p>MS-DOS 와 같은 과거 운영체제</p>
<ul>
<li>MS-DOS는 단일 사용자 단일 프로세스 시스템, 한 프로세스가 전체 메모리 독점</li>
</ul>
</li>
<li><p>고정 크기 할당</p>
<ul>
<li>IBM OS/360 MFT<ul>
<li>메모리 전체를 고정 크기의 n개로 분할. 프로세스마다 하나씩 할당. 수용가능 프로세스의 수 n 고정</li>
<li>메모리가 없을 때, 프로세스는 큐에서 대기</li>
</ul>
</li>
</ul>
</li>
<li><p>가변 크기 할당</p>
<ul>
<li>IBM OS/360 MVT <ul>
<li>프로세스마다 가변 크기로 연속된 메모리 할당. 수용가능 프로세스 수 가변</li>
<li>메모리가 부족할 때, 프로세스는 큐에서 대기</li>
</ul>
</li>
</ul>
</li>
<li><p>가상 메모리 지원 X </p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/858d4da5-51eb-40b2-ba08-9edef6aa84cc/image.png" alt=""></p>
<h2 id="단편화">단편화</h2>
<p>1) 단편화 </p>
<ul>
<li>프로세스에게 할당할 수 없는 조각 메모리들이 생기는 현상, 조각 메모리를 홀(hole)이라고 부름</li>
</ul>
<p>2) 내부 단편화</p>
<ul>
<li><p>할당된 메모리 내부에 사용할 수 없는 홀이 생기는 현상</p>
<ul>
<li><p>파티션보다 작은 프로세스를 할당하는 경우 발생</p>
<ul>
<li>IBM OS/360 MFT 사례</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/7c1f378b-fe1c-408d-aa45-e79c04871e2e/image.png" alt=""></p>
</li>
</ul>
</li>
</ul>
<p>3) 외부 단편화</p>
<ul>
<li>할당된 메모리들 사이에 사용할 수 없는 홀이 생기는 현상<ul>
<li>가변 크기의 파티션이 생기고 반환되면서 여러 개의 작은 홀 생성<ul>
<li>홀이 프로세스의 크기보다 작으면 할당할 수 없음</li>
<li>IBM OS/360 MVT 사례
<img src="https://velog.velcdn.com/images/passion_man/post/06964d7f-4dec-48f2-97ed-1d10c4f9b5a6/image.png" alt=""></li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="연속-메모리-할당-구현">연속 메모리 할당 구현</h2>
<p>1) 하드웨어 지원</p>
<ul>
<li>CPU 레지스터 필요 <ul>
<li>base 레지스터 : 현재 CPU가 실행 중인 프로세스에게 할당된 물리 메모리의 시작 주소 <ul>
<li>limit 레지스터 : 현재 CPU가 실행 중인 프로세스에게 할당된 메모리 크기</li>
<li>주소 레지스터 : 현재 액세스하는 메모리의 논리 주소</li>
</ul>
</li>
</ul>
</li>
<li>주소 변환 하드웨어(MMU) 필요 - 논리 주소를 물리 주소로 변환하는 장치</li>
</ul>
<p>2) 운영체제 지원</p>
<ul>
<li>모든 프로세스에 대해 프로세스별로 할당된 &#39;물리메모리 시작 주소와 크기 정보 저장&#39; 관리</li>
<li>비어있는 메모리 영역 관리</li>
<li>새 프로세스를 스케줄링하여 실행시킬 때마다, &#39;물리 메모리의 시작 주소와 크기 정보&#39;를 CPU 내부의 base 레지스터와 limit 레지스터에 적재</li>
</ul>
<p>3) 연속 메모리 할당의 장단점</p>
<ul>
<li>장점 
1) 논리 주소를 물리 주소로 바꾸는 과정이 단순. CPU의 메모리 액세스 속도 빠름
2) 운영체제가 관리할 정보량이 적어서 부담이 덜함</li>
<li>단점
1) 메모리 할당의 유연성이 떨어짐. 작은 홀들을 합쳐 충분한 크기의 메모리가 있음에도, 연속된 메모리를 할당할 수 없는 경우 발생 (-&gt; 메모리 압축 기법으로 해결) </li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/beef4f3d-bbaa-4727-8bad-2fe9b3b5bf4a/image.png" alt=""></p>
<h2 id="홀-선택-알고리즘--동적-메모리-할당">홀 선택 알고리즘 / 동적 메모리 할당</h2>
<ul>
<li><p>운영체제는 할당 리스트 유지</p>
<ul>
<li>할당된 파티션에 관한 정보를 리스트로 유지 관리<ul>
<li>할당된 위치, 크기, 비어 있는지 유무</li>
</ul>
</li>
</ul>
</li>
<li><p>할당 요청이 발생하였을 때 운영체제의 홀 선택 전략 3가지
1) first-fit(최초 적합)</p>
</li>
<li><p>비어있는 파티션 중 맨 앞에 요청 크기보다 큰 파티션 선택</p>
</li>
<li><p>할당 속도 빠름/단편화 발생 가능성</p>
</li>
</ul>
<p>2) best-fit(최적 적합)</p>
<ul>
<li>비어 있는 파티션 중 요청을 수용하는 가장 작은 파티션 선택</li>
<li>크기 별로 파티션이 정렬되어 있지 않으면 전부 검색</li>
<li>가장 작은 홀 생성됨</li>
</ul>
<p>3) worst-fit(최악 적합)</p>
<ul>
<li>비어 있는 파티션 중 요청을 수용하는 가장 큰 파티션 선택</li>
<li>크기 별로 파티션이 정렬되어 있지 않으면 전부 검색</li>
<li>가장 큰 홀 생성됨</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/6db76f35-4ff5-45a0-a53f-6c6fafcbe441/image.png" alt=""></p>
<h1 id="세그먼테이션-메모리-관리">세그먼테이션 메모리 관리</h1>
<h2 id="세그먼테이션-개요">세그먼테이션 개요</h2>
<p>1) 세그먼트</p>
<ul>
<li>세그먼트는 논리적 단위 - 개발자의 관점에서 보는 프로그램의 논리적 구성 단위</li>
<li>세그먼트마다 크기 다름</li>
</ul>
<p>2) 프로그램을 구성하는 일반적인 세그먼트 종류</p>
<ul>
<li>코드 세그먼트</li>
<li>데이터 세그먼트</li>
<li>스택 세그먼트</li>
<li>힙 세그먼트</li>
</ul>
<p>3) 세그먼테이션 기법</p>
<ul>
<li>프로세스를 논리 세그먼트 크기로 나누고, 각 논리 세그먼트를 한 덩어리의 물리 메모리에 할당하고 관리하는 메모리 관리 기법]</li>
<li>프로세스의 주소 공간<ul>
<li>프로세스의 주소 공간을 여러 개의 논리 세그먼트들로 나누고<ul>
<li>각 논리 세그먼트를 물리 세그먼트에 매핑</li>
<li>프로세스를 논리 세그먼트로 나누는 과정은 컴파일러, 링커, 로더, 운영체제에 의해 이루어짐</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>4) 논리 세그먼트와 물리 세그먼트의 매핑
    - 시스템 전체 세그먼트 매핑 테이블을 두고 논리 주소를 물리 주소로 변환
5) 외부 단편화 발생</p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/504a7a8c-9487-40e3-9d15-8fa0b282e7d9/image.png" alt=""></p>
<h2 id="세그먼테이션의-구현">세그먼테이션의 구현</h2>
<p>1) 하드웨어 지원</p>
<ul>
<li>논리 주소 구성 : [세그먼트 번호, 옵셋]<ul>
<li>옵셋 : 세그먼트 내 상대 주소</li>
</ul>
</li>
<li>CPU <ul>
<li>세그먼트 테이블의 시작 주소를 가리키는 레지스터 필요</li>
</ul>
</li>
<li>MMU 장치<ul>
<li>논리 주소를 물리 주소로 변환하는 장치<ul>
<li>논리 주소가 세그먼트 범위를 넘는지 판별(메모리 보호)</li>
<li>논리 주소의 물리 주소 변환(메모리 할당)</li>
</ul>
</li>
</ul>
</li>
<li>세그먼트 테이블<ul>
<li>메모리에 저장<ul>
<li>세그먼트별로 시작 물리 주소와 세그먼트 크기 정보</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>2) 운영체제 지원</p>
<ul>
<li>세그먼트의 동적 할당/반환 및 세그먼트 테이블 관리 기능 구현<ul>
<li>프로세스의 생성/소멸에 따라 동적으로 세그먼트 할당/반환<ul>
<li>물리 메모리에 할당된 세그먼트 테이블과 자유 공간에 대한 자료 유지</li>
<li>컨텍스트 스위칭 때 CPU의 레지스터에 적절한 값 로딩 
3) 컴파일러, 링커, 로더 지원</li>
</ul>
</li>
</ul>
</li>
<li>사용자 프로그램을 세그먼트 기반으로 컴파일, 링킹, 로딩</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/c98b8be4-f173-49e2-ac75-f7022306d92b/image.png" alt=""></p>
<h2 id="단편화-1">단편화</h2>
<ul>
<li><p>외부 단편화 발생</p>
<ul>
<li>세그먼트들의 크기가 같지 않기 때문에 세그먼트와 세그먼트 사이에 발생하는 작은 크기의 홀</li>
</ul>
</li>
<li><p>내부 단편화 발생 없음</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] 7. 교착상태]]></title>
            <link>https://velog.io/@passion_man/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-7.-%EA%B5%90%EC%B0%A9%EC%83%81%ED%83%9C</link>
            <guid>https://velog.io/@passion_man/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-7.-%EA%B5%90%EC%B0%A9%EC%83%81%ED%83%9C</guid>
            <pubDate>Mon, 30 May 2022 04:46:10 GMT</pubDate>
            <description><![CDATA[<p>교착 상태 : 자원을 소유한 채, 모두 상대방이 소유한 자원을 기다리면서 무한 대기</p>
<h2 id="식사하는-철학자-문제">식사하는 철학자 문제</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/2211a645-540a-4dfc-8187-8d2967204889/image.png" alt=""></p>
<h2 id="철학자들의-교착상태-원인과-해결">철학자들의 교착상태 원인과 해결</h2>
<ul>
<li>교착상태 원인 - 환형 요청/대기(circular wait)<ul>
<li>5명 모두 왼쪽 포크를 가지고 오른쪽 포크를 요청하는 환형 고리<ul>
<li>환형 고리는 스스로 인식이나 해체 불가</li>
</ul>
</li>
</ul>
</li>
<li>교착 상태 해결 - &#39;환형 대기&#39;가 생기지 않도록<ul>
<li>마지막 철학자(5번)만 오른쪽 포크를 먼저 잡고 왼쪽을 잡도록 규칙 수정 </li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/1960e860-949c-48fe-8734-1112fed082fd/image.png" alt=""></p>
<h2 id="식사하는-철학자-문제는-교착-상태-문제를-비유">식사하는 철학자 문제는 교착 상태 문제를 비유</h2>
<ul>
<li>교착상태는 다중프로그래밍 시스템 초기에 노출된 문제점 <ul>
<li>철학자 : 프로세스<ul>
<li>포크 : 자원</li>
<li>스파게티 : 프로세스가 처리할 작업</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/881ee47c-4940-4488-be92-c34a6d51db6c/image.png" alt=""></p>
<h1 id="교착상태">교착상태</h1>
<p>1) 교착상태(deadlock)</p>
<ul>
<li>자원을 소유한 스레드들 사이에서, 각 스레드는 다른 스레드가 소유한 자원을 요청하여 무한정 대기하고 있는 현상<ul>
<li>deadly embrace : 풀지 못하는 포옹<ul>
<li>교착상태 문제는 1965년 Dijkstra의 banker&#39;s algorithm research 에서 처음 제기
2) 교착상태 발생 위치</li>
</ul>
</li>
</ul>
</li>
<li>사용자가 작성한 멀티스레드 응용프로그램에서 주로 발생<ul>
<li>정교하지 못한 코딩에서 비롯</li>
</ul>
</li>
<li>커널 내에서도 발생<ul>
<li>거의 발생하지 않음, 매우 정교하게 작성되기 때문</li>
</ul>
</li>
<li>교착상태를 막도록 운영하는 컴퓨터 시스템은 거의 없는 실상<ul>
<li>막는데 많은 시간과 공간의 비용이 들기 때문<ul>
<li>교착상태가 발생하도록 두고, 교착상태가 발생한 것 같으면, 시스템 재시작, 혹은 의심스러운 몇몇 프로그램 종료</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>3) 교착생태의 전형적인 발생 상황</p>
<ul>
<li>2개의 스레드가 각각 락 소유, 상대가 가진 락 요청하고 기다릴 때<ul>
<li>단일 CPU/ 다중 CPU 모두에서 발생, T1과 T2가 서로 다른 CPU에서 실행될 때도 발생 </li>
</ul>
</li>
<li>락과 자원에 대한 경쟁이 있는 한 교착상태는 언제든 발생 가능</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/961baecc-4319-48e2-894f-b040a19639f3/image.png" alt=""></p>
<h2 id="교착상태를-유발시킬-수-있는-컴퓨터-시스템의-잠재적-요인">교착상태를 유발시킬 수 있는 컴퓨터 시스템의 잠재적 요인</h2>
<ol>
<li>자원</li>
</ol>
<ul>
<li>교착상태의 발생지<ul>
<li>교착상태는 멀티스레드가 자원을 동시에 사용하려는 충돌이 요인</li>
</ul>
</li>
<li>컴퓨터 시스템에는 많은 자원 존재<ul>
<li>소프트웨어 자원 - 뮤텍스, 스핀락, 세마포, 파일, 데이터베이스, 파일 락<ul>
<li>하드웨어 자원 - 프린터, 메모리, 프로세스 등</li>
</ul>
</li>
</ul>
</li>
</ul>
<ol start="2">
<li>자원과 스레드</li>
</ol>
<ul>
<li>한 스레드가 여러 자원을 동시에 필요로 하는 상황이 요인</li>
</ul>
<ol start="3">
<li>자원과 운영체제</li>
</ol>
<ul>
<li>한 번에 하나씩 자원을 할당하는 운영체제 정책이 요인</li>
</ul>
<ol start="4">
<li>자원 비선점</li>
</ol>
<ul>
<li>할당된 자원은 스레드가 자발적으로 내놓기 전에 강제로 뺏지 못하는 정책이 요인<ul>
<li>운영체제는 스레드가 가진 자원을 강제로 뺏지 못함<ul>
<li>만일 강제로 빼앗을 수 있다면? 교착상태가 발생하지 않게 할 수 있다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="교착상태-모델링">교착상태 모델링</h2>
<p>1) 자원 할당 그래프(Resource Allocation Graph, RAG)</p>
<ul>
<li><p>그래프의 요소</p>
<ul>
<li>꼭지점 - 스레드, 자원<ul>
<li>간선 - 소유/요청 관계. 할당 간선과 요청 간선
1) 할당 간선 : 자원에서 스레드로 향하는 화살표. 할당 받은 상태 표시
2) 요청 간선 : 스레드에서 자원으로 향하는 화살표. 요청 표시</li>
</ul>
</li>
</ul>
</li>
<li><p>자원에 대한 시스템의 상태를 나타내는 방향성 그래프</p>
<ul>
<li>컴퓨터 시스템에 실행 중인 전체 스레드와 자원의 개수</li>
<li>각 자원의 총 인스턴스 개수와 할당 가능한 인스턴스 개수</li>
<li>각 스레드가 할당받아 소유하고 있는 자원의 인스턴스 개수</li>
<li>각 스레드가 실행에 필요한 자원 유형과 인스턴스 개수</li>
</ul>
</li>
</ul>
<p>2) 자원할당 그래프를 통해 교착상태 판단</p>
<ul>
<li>교착상태 예방, 회피, 감지를 위한 알고리즘 개발에 필요</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/b65aa279-b422-4f76-876e-73e8fb61c075/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/20b03010-1e8b-42c4-b123-2f2a6e8d1f3a/image.png" alt=""></p>
<h2 id="교착상태가-발생하는-프로그램-만들기">교착상태가 발생하는 프로그램 만들기</h2>
<pre><code>#include &lt;stdi.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;pthread.h&gt;
#include &lt;unistd.h&gt;

int x = 0; //공유 변수
int y = 0; //공유 변수
pthread_mutex_t lock1; //뮤텍스 락 변수
pthread_mutex_t lock2; //뮤텍스 락 변수

void* worker1(void* arg){ //스레드 코드
    pthread_mutex_lock(&amp;lock1); //x를 독점 사용하기 위해 lock1 잠그기
    printf(&quot;%s lock1 잠금\n&quot;, (char*)arg);
        x++;
        sleep(2); //2초 잠자기

        pthread_mutex_lock(&amp;lock2); //y를 독점 사용하기 위해 lock2 잠그기
        printf(&quot;%s lock2 잠금\n&quot;, (char*)arg); 
        y++;
        pthread_mutex_unlock(&amp;lock2); //lock2 풀기
        printf(&quot;%s lock2 해제\n&quot;, (char*)arg);

    pthread_mutex_unlock(&amp;lock1); //lock1 풀기
    printf(&quot;%s lock1 해제\n&quot;, (char*)arg);
}

void* worker2(void* arg){ //스레드 코드
    pthread_mutex_lock(&amp;lock2); //y를 독점 사용하기 위해 lock2 잠그기
    printf(&quot;%s lock2 잠금\n&quot;, (char*)arg);   
        y++;
        sleep(2); //2초 잠자기

        pthread_mutex_lock(&amp;lock1); //x를 독점 하용하기 위해 lock1 잠그기
        printf(&quot;%s lock1 잠금\n&quot;, (char*)arg);
        x++;
        pthread_mutex_unlock(&amp;lock1); //lock1 풀기
        printf(&quot;%s lock1 해제\n, (char*)arg);

    pthread_mutex_unlock(&amp;lock2); //lock2 풀기
    printf(&quot;%s lock2 해제\n&quot;, (char*)arg);
}

int main(){
    char *name[] = {&quot;황기태&quot;, &quot;이찬수&quot;};
    pthread_t tid[2];

    pthread_mutex_init(&amp;lock1, NULL); //뮤텍스 락 변수 lock1 초기화
    pthread_mutex_init(&amp;lock2, NULL); //뮤텍스 락 변수 lock2 초기화

    pthread_create(&amp;tid[0], NULL, worker1, name[0]); //worker1 스레드 생성
    pthread_create(&amp;tid[1], NULL, worker2, name[1]); //worker2 스레드 생성 

    pthread_join(tid[0], NULL);
    pthread_join(tid[1], NULL);

    pthread_mutex_destroy(&amp;lock2);
    pthread_mutex_destroy(&amp;lock1);

    printf(&quot;x = %d, y = %d\n&quot;, x, y);

    return 0;
}
</code></pre><p><img src="https://velog.velcdn.com/images/passion_man/post/a24333a7-076f-4d78-8820-0bb2c868d1c9/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/fe6b81bf-48c1-4ac6-9a2a-bb63da8727d7/image.png" alt=""></p>
<h1 id="교착상태-해결">교착상태 해결</h1>
<h2 id="교착상태가-발생하는-4가지-필요충분-조건">교착상태가 발생하는 4가지 필요충분 조건</h2>
<p>1) 코프만 조건 </p>
<ul>
<li><p>교착상태가 발생하는 4가지 필요충분 조건</p>
<ul>
<li>Computing Survey, Vol.3, No.2, June, 1971에 실린 논문</li>
</ul>
</li>
<li><p>다음 4가지 상황이 허용되는 시스템은 언제든 교착상태 발생 가능
  1) 상호배제 </p>
<pre><code>  - 각 자원은 한 번에 하나의 스레드에게만 할당
  - 자원이 한 스레드에게 할당되면 다른 스레드에게는 할당될 수 없음    </code></pre><p>  2) 소유하면서 대기(Hold &amp; Wait)</p>
<pre><code>  - 스레드가 한 사원을 소유(lock) 하면서 다른 자원을 기다리기</code></pre><p>  3) 강제 자원 반환 불가(No Preemption)</p>
<pre><code>  - 스레드에게 할당된 자원을 강제로 빼앗지 못함</code></pre><p>  4) 환형 대기(Circular Wait)</p>
<pre><code>     - 한 그룹의 스레드들에 대해 각 스레드는 다른 스레드가 요청하는 자원을 소유하는 원형 고리 형성</code></pre></li>
</ul>
<p>** 4가지 조건 중 한 가지라도 성립되지 않으면 교착상태 발생 X </p>
<blockquote>
<p>교착상태로 인해 시스템 전체가 중단되지는 않는다. 교착상태는 시스템 내에 몇몇 스레드들 사이에서 발생하므로 이들 스레드들만 실행이 중지된 채 대기상태에 머물며, 이들로 인해 시스템 전체가 불능 상태가 되는 것은 아니다. 시스템 관리자나 이들 스레드들을 제거하면 이들의 교착상태는 사라진다. 만일 많은 스레드들이 교착상태에 연루되어 있을 때는 시스템을 재시작 하는 것 좋다.</p>
</blockquote>
<h2 id="교착상태-예방">교착상태 예방</h2>
<p>** 코프만의 4가지 조건 중 최소 하나를 성립하지 못하게 함</p>
<ol>
<li>상호배제 조건 -&gt; 상호배제 없애기</li>
</ol>
<ul>
<li>동시에 2개 이상의 스레드가 자원을 활용할 수 있도록 함</li>
<li>컴퓨터 시스템에서 근본적으로 적용 불가능한 방법</li>
</ul>
<ol start="2">
<li>소유하면서 대기 조건 -&gt; 기다리지 않게</li>
</ol>
<ul>
<li><p>방법1 : 운영체제는 스레드 실행 전 필요한 모든 자원을 파악하고 실행시 한 번에 할당</p>
</li>
<li><blockquote>
<p>당장 사용하지 않는 자원을 스레드에게 묶어 두기 때문에 자원 활용률이 떨어짐</p>
</blockquote>
</li>
<li><blockquote>
<p>다른 스레드는 필요한 자원을 할당 받지 못하고 실행 대기</p>
</blockquote>
</li>
<li><p>방법2 : 스레드가 새로운 자원을 요청하려면, 현재 할당 받은 모든 자원을 반환하고, 한꺼번에 요청하여 할당</p>
</li>
</ul>
<p>=&gt; 방법1이나 방법2 모두 가능하지 않거나 매우 비효율적인 방법</p>
<ol start="3">
<li>강제 자원 반환 불가 조건 -&gt; 선점 허용</li>
</ol>
<ul>
<li>자원을 강제로 반환하게 된 스레드가 자원을 다시 사용하게 될 때 이전 상태로 되돌아갈 수 있도록 상태를 관리할 필요</li>
<li>간단히 않고 오버헤드도 매우 큼</li>
</ul>
<ol start="4">
<li>환형 대기 조건 -&gt; 환형 대기 제거</li>
</ol>
<ul>
<li>모든 자원에게 번호를 매기고, 번호순으로 자원을 할당 받게 함</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/dd34720a-9bd7-499b-a538-a71b2a50be3c/image.png" alt=""></p>
<h2 id="교착상태-회피">교착상태 회피</h2>
<ul>
<li><p>자원 할당 시, 미래에 환형 대기가 발생할 것으로 판단되면 자원 할당을 하지 않는 정책</p>
</li>
<li><p>banker&#39;s 알고리즘으로 해결
  1) Edsger Dijkstra 에 의해 개발된 알고리즘. 자원 할당 전에 미래에 교착상태가 발생하지 않을 것인지 안전한지 판단하는 알고리즘</p>
<pre><code> - 은행에서의 대출 알고리즘</code></pre><p>  2) 안전한 상태</p>
<pre><code> - 현재 프로세스들을 어떤 순서로 실행시켰을 때, 모든 프로세스들이 자신이 요청하는 자원을 가지고 실행할 수 있다면 안전한 상태</code></pre><p>  3) 불안전한 상태</p>
<pre><code> - 환형 대기에 빠질 수 있다면 불안전한 상태 </code></pre><p>  4) 알고리즘</p>
<pre><code> - 각 프로세스가 실행 시작 전에 필요한 전체 자원의 수를 운영체제에게 알림
 - 자원을 할당할 때마다, 자원을 할당해주었을 때 교착상태가 발생하지 않을 만큼 안전한 상태인지 판단하여 안전한 상태일 때만 자원할당
 - 각 프로세스가 필요한 자원의 개수, 현재 각 프로세스가 할당 받은 자원의 개수, 그리고 시스템 내 할당 가능한 자원의 개수를 토대로 현재 요청된 자원을 할당해도 안전한지 판단</code></pre><p>  5) 비현실적</p>
<pre><code> - 각 프로세스가 실행 전에 필요한 자원의 개수를 아는 것은 불가능
 - 프로세스의 개수도 동적으로 변하기 때문에 미리 프로세스의 개수를 정적으로 고정시키는 것은 불가능</code></pre></li>
</ul>
<h2 id="교착상태-감지-및-복구">교착상태 감지 및 복구</h2>
<p>1) 교착상태를 감지하는 프로그램을 통해, 형성된 교착상태를 푼다.</p>
<ul>
<li>백그라운드에서 교착상태를 감지하는 프로그램 늘 실행</li>
</ul>
<p>2) 교착상태를 감지하였을 때의 복구 방법</p>
<ul>
<li><p>자원 강제 선점</p>
</li>
<li><blockquote>
<p>교착상태에 빠진 스레드 중 하나의 자원을 강제로 빼앗아 다른 스레드에게 할당</p>
</blockquote>
</li>
<li><p>롤백</p>
</li>
<li><blockquote>
<p>운영체제는 주기적으로 교착상태가 발생할 것으로 예측도는 스레드의 상태를 저장하여 두고 교착상태가 발생하면 마지막으로 저장된 상태로 돌아가도록 하고, 다시 시작하면서 자원을 다르게 할당</p>
</blockquote>
</li>
<li><p>스레드 강제 종료</p>
</li>
<li><blockquote>
<p>교착상태에 빠진 스레드 중 하나 강제 종료</p>
</blockquote>
</li>
<li><blockquote>
<p>가장 간단하면서도 효과적인 방법</p>
</blockquote>
</li>
<li><p>시간과 메모리 공간(rollback의 경우)에 대한 부담이 크기 때문에 잘 사용하지 않음</p>
</li>
</ul>
<blockquote>
<p>교착상태 발생위치 - 교착상태는 사용자가 작성한 멀티스레드 응용프로그램에서 주로 발생하며 개발자의 미숙한 멀티스레드 코딩에서 비롯된다. 교착상태는 커널 내에서도 발생할 수 있지만 거의 발생하지 않는다. 커널의 최고의 개발자들에 의해 매우 정교하게 작성되어 있기 때문이다.</p>
</blockquote>
<h2 id="교착상태-무시--타조-알고리즘">교착상태 무시 : 타조 알고리즘</h2>
<p>1) 교착상태를 해결할 필요가 있을까?</p>
<ul>
<li>교착상태에 대한 통계치는 없다.</li>
<li>교착상태는 반드시 발생<ul>
<li>하지만 교착상태의 발생 가능성이 극히 적고<ul>
<li>교착상태를 피하기 위한 비용이 많이 들어감</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>2) 타조알고리즘</p>
<ul>
<li><p>Put your head in the sand 접근법</p>
<ul>
<li>타조가 머리를 모래 속에 박조 자신이 보이지 않는 척하는 것</li>
<li>교착상태는 발생하지 않을 거야하고 아무 대책을 취하지 않는 접근법</li>
</ul>
</li>
<li><p>Unix 와 Window 등 현재 거의 모든 운영체제에서 사용</p>
<ul>
<li>의심가는 스레드를 종료시키거나 시스템 재시작</li>
<li>거의 발생하지 않거나 아주 드물게 발생하는 것에 비해 교착상태 해결에는 상대적으로 비용이 많이 들기 때문</li>
</ul>
</li>
</ul>
<p>3) 주의</p>
<ul>
<li>핵 시스템, 비행기, 미사일 등 시스템 재시작이 파국을 초래할 hard real-time 시스템이나 환자 감지 시스템 등에서는 적합하지 않음<ul>
<li>이런 시스템에서는 자원에 대한 프로세스의 할당 등에 대해 미리 알고 적절한 조치가 필요</li>
</ul>
</li>
</ul>
<h2 id="교착상태를-다루는-현실적인-방안">교착상태를 다루는 현실적인 방안</h2>
<ul>
<li>대부분의 운영체제 : ostrich 알고리즘 사용</li>
<li>교착상태가 일어나지 않을 것으로 가정하고, 교착상태에 대한 아무 대책을 세우지 않음<ul>
<li>교착상태가 발생할 확률은 극히 작음</li>
</ul>
</li>
<li>교착상태 예방, 회피, 감지에는 많은 오버헤드가 소모되므로</li>
<li>교착상태가 발생하면 시스템 재시작 혹은 특정 프로세스/스레드 강제 종료<ul>
<li>관련된 데이터를 잃어버릴 수 있음<ul>
<li>하지만 전체적으로 크지 않은 손실</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>이 글이 문제가 된다면 삭제하겠습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] 6. 스레드 동기화]]></title>
            <link>https://velog.io/@passion_man/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-6.-%EC%8A%A4%EB%A0%88%EB%93%9C-%EB%8F%99%EA%B8%B0%ED%99%94</link>
            <guid>https://velog.io/@passion_man/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-6.-%EC%8A%A4%EB%A0%88%EB%93%9C-%EB%8F%99%EA%B8%B0%ED%99%94</guid>
            <pubDate>Mon, 30 May 2022 04:44:51 GMT</pubDate>
            <description><![CDATA[<h1 id="스레드-동기화의-필요성">스레드 동기화의 필요성</h1>
<h2 id="스레드-동기화의-필요성-1">스레드 동기화의 필요성</h2>
<ul>
<li>다수의 스레드가 동시에 공유 데이터에 접근하면 <ul>
<li>공유 데이터가 훼손되는 문제 발생</li>
</ul>
</li>
<li>스레드 동기화<ul>
<li>공유 데이터에 대한 다수의 스레드가 동시에 접근할 때 공유데이터가 훼손되는 문제의 해결책<ul>
<li>공유데이터를 접근하고자 하는 다수의 스레드가 충돌없이 공유데이터에 접근하기 위해 상호 협력하는 것</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/6e2259b4-14dd-4d0d-9771-0ba7da694001/image.png" alt=""></p>
<h2 id="공유-데이터-접근-문제의-해결책">공유 데이터 접근 문제의 해결책</h2>
<ul>
<li><p>문제점</p>
<ul>
<li>여러 스레드가 공유 변수에 접근할 때, 공유데이터 훼손</li>
</ul>
</li>
<li><p>해결책 : 스레드 동기화</p>
<ul>
<li>한 스레드가 공유데이터에 대한 접근을 마칠 때까지<ul>
<li>다른 스레드가 공유 데이터를 접근하지 못하도록 제어</li>
</ul>
</li>
</ul>
</li>
<li><p>멀티스레드의 경쟁 상황이 자주 발생하는가?</p>
<ul>
<li>매우 자주 발생<ul>
<li>커널 코드에서 자주 발생 (커널에 공유데이터가 많기 때문)<ul>
<li>다중 코어에서 더욱 조심</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="임계구역과-상호배제">임계구역과 상호배제</h2>
<ul>
<li>스레드 동기화와 관련된 2가지 중요 개념 : 임계구역과 상호배제</li>
<li>임계구역<ul>
<li>공유데이터에 접근하는 프로그램 코드들</li>
</ul>
</li>
<li>상호배제<ul>
<li>임계구역이 오직 한 스레드만 배타독점적으로 사용되도록 하는 기술
  1) 임계구역에 먼저 진입한 스레드가 임계구역의 실행을 끝낼 때까지
  2) 다른 스레드가 진입하지 못하도록 보장</li>
</ul>
</li>
</ul>
<h1 id="상호배제">상호배제</h1>
<h2 id="상호배제를-포함하는-프로그램">상호배제를 포함하는 프로그램</h2>
<ol>
<li>일반코드(non-critical code)</li>
</ol>
<ul>
<li>공유데이터를 액세스하지 않는 코드</li>
</ul>
<ol start="2">
<li>임계구역 진입 코드(entry code)</li>
</ol>
<ul>
<li>상호배제를 위해 필요한 코드<ul>
<li>임계구역에 진입하기 전 필요한 코드 블록</li>
</ul>
</li>
<li>현재 임계구역을 실행 중인 스레드가 있는지 검사<ul>
<li>없다면, 다른 스레드가 들어오지 못하도록 조치<ul>
<li>있다면, 진입이 가능해질 때까지 대기</li>
</ul>
</li>
</ul>
</li>
</ul>
<ol start="3">
<li>임계구역 코드(critical code)</li>
<li>임계구역 진출 코드(exit code) </li>
</ol>
<ul>
<li>상호배제를 위해 필요한 코드<ul>
<li>임계구역의 실행을 마칠 때 실행되어야 하는 코드 블록</li>
</ul>
</li>
<li>entry code에서 대기중인 스레드가 임계구역에 진입할 수 있도록 entry code 에서 취한 조치를 해제하는 코드</li>
</ul>
<h2 id="상호배제-구현">상호배제 구현</h2>
<ul>
<li><p>상호배제 구현 목표</p>
<ul>
<li>임계구역에 오직 1개의 스레드만 진입</li>
</ul>
</li>
<li><p>상호배제 구현 방법</p>
<ul>
<li>소프트웨어적 방법 - Peterson&#39;s 알고리즘 등<ul>
<li>하드웨어적 방법 - 인터럽트 서비스 금지, 원자 명령 활용 (오늘날 대부분 하드웨어 솔루션 사용)</li>
</ul>
</li>
</ul>
</li>
<li><p>하드웨어적 방법</p>
</li>
<li><p>임계 구역 진입/진출 코드에 구현</p>
</li>
<li><p>방법1 - 인터럽트 서비스 금지</p>
<ul>
<li>인터럽트가 발생해도 CPU가 인터럽트를 무시하도록 하는 CPU 명령 이용</li>
</ul>
</li>
<li><p>방법2 - 원자 기계 명령 사용</p>
<ul>
<li>상호배제 구현에 가장 많이 사용하는 방법<ul>
<li>임계구역에 진입할 때, 임계구역을 잠그고 들어가는 명령 하나(원자명령)로 다른 스레드가 들어오지 못하게 하는 방법</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="상호배제-구현-방법1---인터럽트-서비스-금지">상호배제 구현 방법1 - 인터럽트 서비스 금지</h2>
<p>1) 인터럽트 서비스 금지 방법</p>
<ul>
<li>임계구역 entry 코드에서 인터럽트 서비스를 금지하는 명령 실행<blockquote>
</blockquote>
cli        ; entry 코드. 인터럽트 서비스 금지 명령 cli (clear interrupt flag)
...
임계구역 코드
...
sti        ; exit 코드. 인터럽트 서비스 명령 허용 sti (set interrupt flag)</li>
</ul>
<p>1) 장치로부터 인터럽트가 발생해도, CPU가 인터럽트 발생을 무시
2) 인터럽트가 발생해도 CPU는 인터럽트 서비스 루틴을 실행하지 않음
3) 인터럽트를 무시하면 임계구역을 실행하는 스레드가 중단되지 않음</p>
<p>2) 문제점</p>
<ul>
<li>모든 인터럽트가 무시되는 문제 발생</li>
<li>멀티코어 CPU나 다중 CPU를 가진 시스템에서 활용 불가<ul>
<li>한 CPU의 인터럽트 금지로 다른 CPU에게 까지 인터럽트 금지는 불가하다. </li>
<li>해결 방법 : CPU는 lock 접두어가 붙은 명령을 처리할 때, CPU의 LOCK핀에 신호를 발생시켜 현재 액세스하고 있는 메모리에 다른 프로세서들이 접근하지 않도록 한다. 그러므로 컴퓨터 설계자는 LOCK 신호를 이용하여 다른 프로세서의 공유 메모리 접근을 막도록 회로를 구성하여야 한다. </li>
</ul>
</li>
</ul>
<h1 id="단순-lock변수로-상호배제-시도">단순 lock변수로 상호배제 시도</h1>
<ul>
<li>locking/unlocking 방식으로 임계구역의 entry/exit 코드 작성하면 상호배제가 가능할까?<ul>
<li>lock 변수 : 1이면 잠금상태</li>
<li>lock 변수 : 0이면 열린상태 </li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/c924415a-c83d-4fa7-8ee1-71ac93b8b213/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/feb60b1d-1199-456a-9982-c70afaeac149/image.png" alt=""></p>
<h1 id="상호배제구현-방법2---원자명령-사용">상호배제구현 방법2 - 원자명령 사용</h1>
<ul>
<li><p>lock 변수를 이용한 상호배제의 실패 원인</p>
<ul>
<li>실패 원인은 entry code에 있음<ul>
<li>lock 변수 값을 읽는 명령과 lock 변수에 1을 저장하는 2개의 명령 사이에 컨텍스트 스위칭이 될 때 문제 발생</li>
</ul>
</li>
</ul>
</li>
<li><p>해결책 - 원자 명령 도입</p>
<ul>
<li>lock 변수를 읽어들이는 명령과 lock 변수에 1을 저장하는 2개의 명령을 한 번에 처리하는 원자 명령 필요<ul>
<li>원자 명령 : TSL (Test and Set Lock)<ul>
<li>1970년대 Intel Pentium에서 시작. 대부분의 CPU에서 제공</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/2fdb361f-7d39-455d-b638-6b3fb6f7204e/image.png" alt=""></p>
<h1 id="멀티스레드-동기화-기법">멀티스레드 동기화 기법</h1>
<h2 id="멀티스레드-동기화">멀티스레드 동기화</h2>
<p>1) 멀티스레드 동기화란?</p>
<ul>
<li>상호배제 기반위에</li>
<li>자원을 사용하려는 여러 스레드들이 자원을 원활히 공유할 수 있도록 하는 기법</li>
<li>동기화 프리미티브(synchronization primitives)로 부름</li>
</ul>
<p>2) 대표적인 기법</p>
<ul>
<li><p>lock 방식 : 뮤텍스(mutex), 스핀락(spilock)</p>
<ul>
<li>상호배제가 되도록 만들어진 락(lock)활용</li>
<li>락을 소유한 스레드만이 임계구역 진입</li>
<li>락을 소유하지 않은 스레드는 락이 풀릴 때까지 대기</li>
</ul>
</li>
<li><p>wait-signal 방식 : 세마포(semaphore)</p>
<ul>
<li>n개의 자원을 사용하려는 m개 멀티스레드의 원활한 관리</li>
<li>자원을 소유하지 못한 스레드는 대기(wait)</li>
<li>자원을 다 사용한 스레드는 알림(signal)</li>
</ul>
</li>
</ul>
<h2 id="뮤텍스">뮤텍스</h2>
<ul>
<li>mutual exclusion 의 약자이다.</li>
</ul>
<p>1) 뮤텍스</p>
<ul>
<li>잠김/열림 중 한 상태를 가지는 lock 변수 이용</li>
<li>한 스레드만 임계구역에 진입시킴</li>
<li>다른 스레드는 큐에 대기</li>
<li>sleep-waiting lock 기법</li>
</ul>
<p>2) 구성요소</p>
<ol>
<li>락 변수</li>
</ol>
<ul>
<li>true/false 중 한 값</li>
<li>true : 락을 잠근다. 락을 소유한다.</li>
<li>false : 락을 연다. 락을 해제한다.</li>
</ul>
<ol start="2">
<li>대기 큐</li>
</ol>
<ul>
<li>락이 열리기를 기다리는 스레드 큐</li>
</ul>
<ol start="3">
<li>연산</li>
</ol>
<ul>
<li>lock 연산(임계구역은 entry code)</li>
<li>락이 잠김 상태(lock = ture) 이면, 현재 스레드를 블록 상태로 만들고 대기 큐에 삽입</li>
<li>락이 열린 상태이면, 락을 잠그고 임계구역 진입
<img src="https://velog.velcdn.com/images/passion_man/post/b99e4a2f-090f-4b52-9020-75b77af94249/image.png" alt=""></li>
</ul>
<h2 id="뮤텍스의-특징">뮤텍스의 특징</h2>
<p>1) 뮤텍스를 이용한 동기화 특징</p>
<ul>
<li>임계구역의 실행시간이 짧은 경우, 비효율적<ul>
<li>락이 잠겨 있으면(컨택스트 스위칭되어) 대기 큐에서 대기, 락이 풀리면 다시(컨택스트 스위칭되어) 실행 -&gt; 락이 잠겨 있는 시간보다 스레드가 잠자고 깨는데 걸리는 시간이 상대적으로 크기 때문</li>
</ul>
</li>
</ul>
<p>2) 뮤텍스 동기화를 위한 POSIX 표준 라이브러리</p>
<ul>
<li>뮤텍스락 변수<ul>
<li>pthread_mutex_t lock;</li>
</ul>
</li>
<li>뮤텍스 조작 함수들<ul>
<li>pthread_mutex_init() - 뮤텍스락 변수 초기화<ul>
<li>pthread_mutex_lock() - 뮤텍스락 잠그기</li>
<li>pthread_mutex_unlock() - 뮤텍스락 풀기</li>
<li>pthread_mutex_destroy() - 뮤텍스락 변수 사용 종료</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>3) pthread를 이용한 뮤텍스 동기화 코딩 사례</p>
<pre><code>pthread_mutex_t lock;                //뮤텍스락 변수 생성
pthread_mutex_init(&amp;lock, NULL);    //뮤텍스락 변수 초기화
pthread_mutex_lock(&amp;lock);            //임계구역 entry 코드. 뮤텍스락 잠그기

...임계구역 코드...

pthread_mutex_unlock(&amp;lock);        //임계구역 exit 코드. 뮤텍스락 열기</code></pre><h2 id="pthread의-뮤텍스를-이용한-공유집계판의-스레드-동기화">pthread의 뮤텍스를 이용한 공유집계판의 스레드 동기화</h2>
<pre><code>#include &lt;stdio.h&gt;
#include &lt;pthread.h&gt;

int sum = 0;
pthread_mutext_t lock;

void* worker(void arg){
    printf(&quot;%s 시작 \t %d\n&quot;, (char*)arg, sum);

    for(int i = 0; i &lt; 1000000 ; i++){
        pthread_mutex_lock(&amp;lock);
        sum = sum + 10;
        pthread_mutex_unlock(&amp;lock);
    }
    printf(&quot;%s 끝 \t %d\n&quot;, (char*)arg, sum);
}

int main(){
    char *name[] = {&quot;황기태&quot;, &quot;이찬수&quot;};
    pthread_t tid[2];
    pthread_attr_t attr[2]; //스레드 정보를 담을 구조체

    pthread_attr_init(&amp;attr[0]);
    pthread_attr_init(&amp;attr[1]);

    pthread_mutex_init(&amp;lock, NULL);

    pthread_create(&amp;tid[0], &amp;attr[0], worker, name[0]);
    pthread_create(&amp;tid[1], &amp;attr[1], worker, name[1]);

    pthread_join(tid[0], NULL);
    pthread_join(tid[1], NULL);

    printf(&quot;최종 sum = %d\n&quot;, sum);

    pthread_mutex_destroy(&amp;lock);

    return 0;
}
</code></pre><p><img src="https://velog.velcdn.com/images/passion_man/post/dd8f1e01-d1db-4b23-8d54-798900ff9ed0/image.png" alt=""></p>
<h2 id="스핀락">스핀락</h2>
<p>1) 스핀락</p>
<ul>
<li>busy-waiting lock 기법<ul>
<li>스레드가 큐에서 대기하지 않고 락이 열릴 때까지 계속 락 변수 검사</li>
</ul>
</li>
<li>뮤텍스와 거의 같고 busy-waiting 이라는 점에서만 다름<ul>
<li>대기큐 없음<ul>
<li>busy-waiting 으로 인해 CPU를 계속 소모. CPU가 다른 스레드를 실행시킬 수 없음</li>
</ul>
</li>
</ul>
</li>
<li>lock을 소유한 스레드만 자원 배타적 사용하는 동기화 기법<ul>
<li>공유자원 하나 당 하나의 스핀락 사용</li>
</ul>
</li>
</ul>
<p>2) 구성요소</p>
<ol>
<li><p>락 변수</p>
<ul>
<li>true/false 중 한 값<ul>
<li>true : 락을 잠근다. 락을 소유한다.</li>
<li>false : 락을 연다. 락을 해제한다.</li>
</ul>
</li>
</ul>
</li>
<li><p>연산</p>
</li>
</ol>
<ul>
<li><p>lock 연산</p>
<ul>
<li>임계구역에 들어갈 때 실행되는 entry code<ul>
<li>락이 잠김 상태면, 락이 풀릴 때까지 무한 루프 돌면서 lock 연산 시도</li>
<li>락이 열린 상태면, 락을 잠김 상태로 바꾸고 임계구역 실행</li>
</ul>
</li>
</ul>
</li>
<li><p>unlock 연산</p>
<ul>
<li>임계구역을 나올 때 실행하는 exit code<ul>
<li>락을 열림 상태로 변경</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/1a28fc80-d1d1-4fd7-96c1-ca6e68587b50/image.png" alt=""></p>
<h2 id="스핀락-특징">스핀락 특징</h2>
<p>1) 스핀락을 이용한 동기화 특징</p>
<ul>
<li><p>뮤텍스의 non-blocking 모델</p>
<ul>
<li>락이 잠겨 있을 때 블록되지 않고 락이 풀릴 때까지 검사 코드 실행</li>
</ul>
</li>
<li><p>단일 CPU를 가진 운영체제에서 비효율적, 멀티코어에 적합</p>
<ul>
<li>단일 코어 CPU에서 의미 없는 CPU 시간 낭비 (Lock을 갖고 있는 스레드를 풀어주려면 단일 코어 CPU에서는 어차피 컨택스트 스위칭을 해야하기 때문이다) 
 -&gt; 스핀락을 검사하는 스레드의 타임 슬라이스가 끝날 때까지 다른 스레드는 실행 안 됨. 다른 스레드의 실행 기회 뺏음
 -&gt; 락을 소유한 다른 스레드가 실행되어야 락이 풀림<ul>
<li>임계구역의 실행 시간이 짧은 경우 효과적</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>2) 스핀락 동기화를 위한 POSIX 표준 라이브러리</p>
<ul>
<li>스핀락 변수<ul>
<li>pthread_spin_t lock;</li>
</ul>
</li>
<li>스핀락 조작 함수들<ul>
<li>pthread_spin_init() - 스핀락 변수 초기화<ul>
<li>pthread_spin_lock() - 스핀락 잠그기</li>
<li>pthread_spin_unlock() - 스핀락 풀기</li>
<li>pthread_spin_destroy() - 스핀락 변수 사용 종료</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>3) pthread를 이용한 스핀락 동기화 코딩 사례</p>
<pre><code>pthread_spinlock_t lock;        //스핀락 변수 생성
pthread_spin_init(&amp;lock, NULL);    //스핀락 변수 초기화
pthread_spin_lock(&amp;lock);        //임계구역 entry code. 스핀락 잠그기

... 임계구역 코드 ...

pthread_spin_unlock(&amp;lock);        //임계구역 exit code. 스핀락 열기 </code></pre><h2 id="pthread의-스핀락을-이용한-공유-집계판의-스레드-동기화">pthread의 스핀락을 이용한 공유 집계판의 스레드 동기화</h2>
<pre><code>#include &lt;stdio.h&gt;
#include &lt;pthread.h&gt;

int sum = 0;
pthread_spinlock_t lock;

void* worker(void arg){
    printf(&quot;%s 시작 \t %d\n&quot;, (char*)arg, sum);

    for(int i = 0; i &lt; 1000000 ; i++){
        pthread_spin_lock(&amp;lock);
        sum = sum + 10;
        pthread_spin_unlock(&amp;lock);
    }
    printf(&quot;%s 끝 \t %d\n&quot;, (char*)arg, sum);
}

int main(){
    char *name[] = {&quot;황기태&quot;, &quot;이찬수&quot;};
    pthread_t tid[2];
    pthread_attr_t attr[2]; //스레드 정보를 담을 구조체

    pthread_attr_init(&amp;attr[0]);
    pthread_attr_init(&amp;attr[1]);

    pthread_spin_init(&amp;lock, PTHREAD_PROCESS_PRIVATE);
    //lock을 한 프로세스에 속한 스레드만이 공유하는 변수로 선언

    pthread_create(&amp;tid[0], &amp;attr[0], worker, name[0]);
    pthread_create(&amp;tid[1], &amp;attr[1], worker, name[1]);

    pthread_join(tid[0], NULL);
    pthread_join(tid[1], NULL);

    printf(&quot;최종 sum = %d\n&quot;, sum);

    pthread_mutex_destroy(&amp;lock);

    return 0;
}</code></pre><p><img src="https://velog.velcdn.com/images/passion_man/post/29207653-92bf-4c4f-9ef9-d8d411883c82/image.png" alt=""></p>
<h2 id="뮤텍스와-스핀락은-어떤-경우에-적합한가">뮤텍스와 스핀락은 어떤 경우에 적합한가?</h2>
<ol>
<li>락이 잠기는 시간이 긴 응용 : 뮤텍스</li>
</ol>
<ul>
<li>락을 얻지 못했을 때, CPU를 다른 스레드에게 양보하는 것이 효율적</li>
<li>락이 잠기는 시간이 짧은 경우 : 스핀락이 효율적</li>
</ul>
<ol start="2">
<li>단일 CPU를 가진 시스템 : 뮤텍스</li>
</ol>
<ul>
<li>단일 CPU에서 스핀락은 크게 의미 없음</li>
</ul>
<ol start="3">
<li>멀티 코어(멀티 CPU)를 가진 시스템 : 스핀락</li>
</ol>
<ul>
<li>잠자고 깨는 컨택스트 스위칭 없이 바로 자원 사용</li>
<li>임계구역은 가능한 짧게 작성하므로</li>
</ul>
<ol start="4">
<li>사용자 응용프로그램 : 뮤텍스, 커널 코드 : 스핀락 </li>
</ol>
<ul>
<li>커널 코드나 인터럽트 서비스 루틴은 빨리 실행되어야 하고, 인터럽트 서비스 루틴 내에서 잠잘 수 없기 때문</li>
</ul>
<ol start="5">
<li>스핀락을 사용하면 기아 발생 가능</li>
</ol>
<ul>
<li>스핀락은 무한 경쟁 방식이어서 기아가 발생 가능<ul>
<li>락을 소유한 스레드가 락을 풀지 않고 계속 실행하거나 종료해버린 경우, 코딩이 잘못된 경우</li>
</ul>
</li>
</ul>
<h2 id="뮤텍스와-스핀락-비교">뮤텍스와 스핀락 비교</h2>
<table>
<thead>
<tr>
<th></th>
<th>뮤텍스</th>
<th>스핀락</th>
</tr>
</thead>
<tbody><tr>
<td>대기큐</td>
<td>있음</td>
<td>없음</td>
</tr>
<tr>
<td>블록 가능 여부</td>
<td>락이 작겨 있으면 블록됨</td>
<td>락이 잠겨 있어도 블록되지 않고 계속 락 검사</td>
</tr>
<tr>
<td>lock/unlock 연산 비용</td>
<td>저비용</td>
<td>CPU를 계속 사용하므로 고비용</td>
</tr>
<tr>
<td>하드웨어 관련</td>
<td>단일 CPU에서 적합</td>
<td>멀티코어 CPU에서 적합</td>
</tr>
<tr>
<td>주 사용처</td>
<td>사용자 응용 프로그램</td>
<td>커널 코드, 인터럽트 서비스 루틴</td>
</tr>
</tbody></table>
<blockquote>
</blockquote>
<p>왜 알아야 하는가?</p>
<ul>
<li>개발자로서 둘 중 하나를 선택하여야하고, 시스템의 성능 관점에서 볼 수 있어야 하기 때문이다. </li>
</ul>
<h2 id="세마포">세마포</h2>
<ul>
<li>세마포가 필요한 상황 
<img src="https://velog.velcdn.com/images/passion_man/post/ab43e326-63d5-4f33-b85b-c7b3f14fb5fc/image.png" alt=""></li>
</ul>
<p>1) 세마포의 정의</p>
<ul>
<li>멀티스레드 사이의 자언 관리 기법<ul>
<li>n개의 공유 자원을 다수 스레드가 공유하여 사용하도록 돕는 자원 관리 기법 (n개의 프린터가 있는 경우, 프린터를 사용하고자 하는 다수 스레드의 프린터 관리)</li>
</ul>
</li>
</ul>
<p>2) 구성요소</p>
<ol>
<li>자원 : n개</li>
<li>대기 큐 : 자원을 할당 받지 못한 스레드들이 대기하는 큐</li>
<li>counter 변수 </li>
</ol>
<ul>
<li>사용 가능한 자원의 개수를 나타내는 정수형 전역 변수</li>
<li>n으로 초기화 (counter = n)</li>
</ul>
<ol start="4">
<li>P/V 연산</li>
</ol>
<ul>
<li>P연산(wait 연산) - 자원 요청 시 실행하는 연산 (자원 사용 허가를 얻는 과정)</li>
<li>V연산(signal 연산) - 자원 반환 시 실행하는 연산 (자원 사용이 끝났음을 알리는 연산)</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/be6ce4b2-6fc7-43e9-b75f-428e38c50fe5/image.png" alt=""></p>
<h2 id="p연산과-v연산">P연산과 V연산</h2>
<ul>
<li><p>P/V를 wait/signal 로 표기하기도 함</p>
<ul>
<li>P연산 : 자원 사용을 허가하는 과정, 사용 가능 자원 수 1 감소(counter--)<ul>
<li>V연산 : 자원 사용을 마치는 과정, 사용가능 자원 수 1 증가(counter++)</li>
</ul>
</li>
</ul>
</li>
<li><p>세마포 종류 2가지 - 자원을 할당 받지 못한 경우의 행동에 따라 구분
1) sleep-wait 세마포</p>
</li>
<li><p>P연산 : 대기 큐에서 잠자기, V연산 : 사용가능 자원이 있으면 잠자는 스레드 깨우기</p>
<pre><code>P 연산 { 
  counter--;
  if counter &lt; 0 {
  ... 현재 스레드들 대기 큐에 삽입 ... 
  }
  ... 자원 획득 ...
}</code></pre></li>
</ul>
<pre><code>V 연산 {
    counter++;
    if counter &lt;= 0 {
    ... 대기 큐에서 한 스레드 깨움 ...
    }
}</code></pre><p>2) busy-wait 세마포</p>
<ul>
<li>P연산 : 사용 가능 자원이 생길 때까지 무한 루프, V연산 : counter--;</li>
</ul>
<pre><code>P 연산 {
    while counter &lt;= 0;
    counter--;
}</code></pre><pre><code>V 연산 { 
    counter++;
}</code></pre><h2 id="세마포-활용을-위한-posix-표준-라이브러리">세마포 활용을 위한 POSIX 표준 라이브러리</h2>
<p>1) 세마포 구조체</p>
<ul>
<li>sem_t s; // counter 변수 등을 가진 세마포 구조체</li>
</ul>
<p>2) 세마포 조작 함수들</p>
<ul>
<li>sem_init() - 세마포 초기화</li>
<li>sem_destroy() - 세마포 기능 소멸</li>
<li>sem_wait() <ul>
<li>P연산을 수행하는 함수 (blocking call)<ul>
<li>sleep-wait 방식으로, 가용 자원이 없으면 대기 큐에서 잠을 잠</li>
</ul>
</li>
</ul>
</li>
<li>sem_trywait()<ul>
<li>p연산을 수행하는 함수(non-blocking call)<ul>
<li>가용 자원이 있으면, counter 값을 감소시키고 0 리턴</li>
<li>없으면, counter 값을 감소시키지 않고 -1 리턴</li>
</ul>
</li>
</ul>
</li>
<li>sem_post() - V연산을 수행하는 함수</li>
<li>sem_getvalue() - 세마포의 현재 counter 값을 리턴하는 함수</li>
</ul>
<h2 id="세마포-활용-사례">세마포 활용 사례</h2>
<pre><code>#include &lt;stdio.h&gt;
#include &lt;pthread.h&gt;
#include &lt;semaphore.h&gt;
#include &lt;unistd.h&gt;

sem_t toiletsem; // POSIX 세마포 구조체로 모든 스레드에 의해 공유

void* guestThread(void* arg){ // 고객의 행동을 묘사하는 스레드 코드
    int cnt = -1;

    sem_wait(&amp;toiletsem); // P연산. 자원 사용 요청. 세마포의 counter 값 1 감소
    sem_getvalue(&amp;toiletsem, &amp;cnt); // 세마포의 counter 을 cnt 변수로 읽어오기
    printf(&quot;고객%s 화장실에 들어간다.. 세마포 conter = %d\n&quot; ,(char*)arg, cnt); // 1초동안 화장실을 사용한다. 
    sem_post(&amp;toiletsem); // V연산. 화장실 사용을 끝냈을음 알림
       sem_getvalue(&amp;toiletsem, &amp;cnt); // 세마포의 counter 값을 cnt 변수로 읽어오기
    printf(&quot;고객%s 화장실에서 나온다. 세마포 counter = %d\n&quot;, (char*)arg, cnt);
}

#define NO 0 // 자식 프로세스와 세마포 공유하지 않음
#define MAX_COUNTER 3 // 자원의 개수, 동시에 들어갈 수 있는 스레드의 개수

int main(){
    int counter = -1;
    char *name[] = {&quot;1&quot;, &quot;2&quot;, &quot;3&quot;, &quot;4&quot;, &quot;5&quot;};
    pthread_t t[5]; // 스레드 구조체

    //세마포 초기화 : MAX_COUNTER 명이 동시에 사용
    sem_init(&amp;toiletsem, &amp;counter);
    sem_getvalue(&amp;toiletsem, &amp;counter); // 세마포의 현재 counter 값 읽기
    printf(&quot;세마포 counter = %d\n&quot;, counter);

    for(int i = 0; i &lt; 5; i++) pthread_create(&amp;t[i], NULL, guestThread, (void*)name[i]); // 5명의 고객 스레드 생성

    for(int i = 0; i&lt; 5; i++) pthread_join(t[i], NULL); // 모든 고객이 소멸할 때까지 대기

    sem_getvalue(&amp;toiletsem, &amp;counter); // 세마포의 현재 counter 값 읽기

    printf(&quot;세마포 counter = %d\n&quot;, counter);
    sem_destroy(&amp;toiletsem); // 세마포 기능 소멸

    return 0;
}</code></pre><p>-&gt; 3개의 칸이 있는 화장실을 5명의 고객이 사용하고자 할 때 세마포를 이용하여 3칸의 화장실을 5명의 고객 스레드가 활용할 수 있게 관리하는 예시</p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/3ebf0d37-2584-4c4a-ba61-f2d2945b61ba/image.png" alt=""></p>
<h2 id="카운터-세마포와-이진-세마포">카운터 세마포와 이진 세마포</h2>
<p>1) 카운터 세마포</p>
<ul>
<li>자원의 인스턴스가 여러 개인 경우 (앞서 설명)
2) 이진 세마포</li>
<li>자원이 1개 있는 경우 멀티스레드 사이의 자원 관리</li>
<li>1개의 자원에 대해 1개의 스레드만이 액세스할 수 있도록 보호<ul>
<li>뮤텍스와 매우 유사</li>
</ul>
</li>
</ul>
<p>3) 이진 세마포의 구성 요소</p>
<ol>
<li>세마포 변수 S</li>
</ol>
<ul>
<li>0과 1중 하나를 가지는 전역 변수, S는 1로 초기화</li>
</ul>
<ol start="2">
<li>대기큐 </li>
</ol>
<ul>
<li>사용 가능한 자원이 생길 때까지 스레드들이 대기하는 큐</li>
<li>스레드 스케줄링 알고리즘 필요</li>
</ul>
<ol start="3">
<li>2개의 원자 연산</li>
</ol>
<ul>
<li>wait 연산(P연산) - 자원 사용 허가를 얻는 과정<ul>
<li>S가 1 감소 시키고, 0보다 작으면 대기 큐에서 잠듬 0보다 크거나 같으면 자원 사용하는 코드 실행</li>
</ul>
</li>
<li>signal(V연산) - 자원 사용이 끝났음을 알리는 과정<ul>
<li>S를 1 증가시키고, 0보다 크면 그냥 리턴, 0보다 작거나 같으면 대기 큐에 있는 스레드 중 한 개를 깨움</li>
</ul>
</li>
</ul>
<h2 id="동기화-이슈--우선순위-역전">동기화 이슈 : 우선순위 역전</h2>
<ul>
<li><p>우선 순위 역전(priority inversion)</p>
<ul>
<li>스레드의 동기화로 인해 높은 순위의 스레드가 낮은 스레드보다 늦게 스케줄링 되는 현상 -&gt; 우선순위를 기반으로 스케줄링하는 실시간 시스템에서 스레드 동기화로 인해 발생</li>
</ul>
</li>
<li><p>우선 순위 역전의 문제점</p>
<ul>
<li>실시간 시스템의 근본 붕괴
1) 우선 순위가 높다는 것은 중요한 일을 할 가능성, 높은 순위의 스레드가 늦게 실행되면 심각한 문제 발생 가능
2) 낮은 순위의 스레드가 길어지면 더욱 더 심각한 문제 발생</li>
</ul>
</li>
</ul>
<h2 id="우선순위-역전-사례">우선순위 역전 사례</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/f200e613-217a-409c-943e-b42d27576427/image.png" alt=""></p>
<h2 id="우선순위-역전-해결책">우선순위 역전 해결책</h2>
<p>1) 우선순위 올림(priority ceiling)</p>
<ul>
<li>스레드가 공유 자원을 소유하게 될 때, 스레드의 우선순위를 미리 정해진 높은 우선순위로 일시적으로 올림</li>
<li>선점되지 않고 빨리 실행되도록 유도</li>
</ul>
<p>2) 우선순위 상속(priority inheritance)</p>
<ul>
<li>낮은 순위의 스레드가 공유 자원을 가지고 있는 동안</li>
<li>높은 순위의 스레드가 공유 자원을 요청하면</li>
<li>공유 자원을 가진 스레드의 우선순위를 요청한 스레드보다 높게 설정하여 빨리 실행시킴</li>
</ul>
<h1 id="생산자-소비문제">생산자 소비문제</h1>
<h2 id="응용프로그램에-존재하는-생산자-소비자-문제-사례">응용프로그램에 존재하는 생산자 소비자 문제 사례</h2>
<ul>
<li>생산자 소비자 문제는 많은 응용프로그램에서 발생하는 전형적인 동기화 문제
<img src="https://velog.velcdn.com/images/passion_man/post/b5c6ba72-49f2-43f1-9601-b4f4ddb747ec/image.png" alt=""></li>
</ul>
<h2 id="생산자-소비자-문제의-정의">생산자 소비자 문제의 정의</h2>
<p>1) 생산자 소비자 문제란?</p>
<ul>
<li>공유버퍼를 사이에 두고, 공유버퍼에 데이터를 공급하는 생산자들과</li>
<li>공유버퍼에서 데이터를 읽고 소비하는 소비자들이 공유 버퍼를 사용할 때</li>
<li>공유버퍼를 문제 없이 사용하도록 생산자와 소비자를 동기화시키는 문제</li>
<li>멀티스레딩 응용프로그램 작성 시 자주 발생</li>
</ul>
<p>2) 생산자 소비자 문제를 코딩할 때 구체적으로 해결해야하는 3가지 문제</p>
<ul>
<li>문제1<ul>
<li>상호 배제 해결<ul>
<li>생산자들과 소비자들의 공유 버퍼에 대한 상호 배제</li>
</ul>
</li>
</ul>
</li>
<li>문제2<ul>
<li>비어 있는 공유 버퍼 문제(비어 있는 공유버퍼를 소비자가 읽을 때)</li>
</ul>
</li>
<li>문제3<ul>
<li>꽉 찬 공유버퍼 문제(꽉 찬 공유버퍼에 생산자가 쓸 때)</li>
</ul>
</li>
</ul>
<h2 id="비어-있는-공유버퍼-문제-해결">비어 있는 공유버퍼 문제 해결</h2>
<ul>
<li>세마포 R 활용(읽기 가능한 버퍼 개수) : 버퍼가 비어 있는지 살피는 P/V연산으로 해결</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/49ad7ca9-2d2a-4ad6-bf86-53a841165cc3/image.png" alt=""></p>
<h2 id="꽉-찬-공유버퍼-문제-해결">꽉 찬 공유버퍼 문제 해결</h2>
<ul>
<li>세마포 W(쓰기 가능한 버퍼 개수) 활용 : 버퍼가 꽉 차 있을 때 처리하는 P/V연산으로 해결</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/c0149d58-055f-4e9e-bdf6-e6bfd9afaa5a/image.png" alt=""></p>
<h2 id="생산자와-소비자-알고리즘">생산자와 소비자 알고리즘</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/1ef1dee3-7ffd-437a-9670-be5070f02e53/image.png" alt=""></p>
<h2 id="생산자-소비자로-구성된-응용프로그램-만들기">생산자-소비자로 구성된 응용프로그램 만들기</h2>
<ul>
<li><p>생산자 스레드</p>
<ul>
<li>0~9까지 10개의 정수를, 랜덤한 시간 간격으로, 공유버퍼에 쓴다.</li>
</ul>
</li>
<li><p>소비자 스레드</p>
<ul>
<li>공유버퍼로부터 랜덤한 시간 간격으로, 10개의 정수를 읽어 출력한다.</li>
</ul>
</li>
<li><p>공유버퍼</p>
<ul>
<li>4개의 정수를 저장하는 원형 큐로 작성<ul>
<li>원형 큐는 배열로 작성</li>
</ul>
</li>
</ul>
</li>
<li><p>2개의 세마포 사용</p>
<ul>
<li>semWrite : 공유버퍼에 쓰기 가능한 공간(빈 공간)의 개수를 나타냄(초기값이 4인 counter 소유)<ul>
<li>semRead : 공유버퍼에 읽기 가능한 공간(값이 들어 있는 공간)의 개수를 나타냄(초기값이 0인 counter 소유)</li>
</ul>
</li>
</ul>
</li>
<li><p>1개의 뮤텍스 사용</p>
<ul>
<li>pthread_mutex_t critical_section<ul>
<li>공유버퍼에서 읽는 코드와 쓰는 코드를 임계구역으로 설정</li>
<li>뮤텍스를 이용하여 상호배제</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code>#include &lt;stdio.h&gt;
#include &lt;pthread.h&gt;
#include &lt;semaphore.h&gt;
#include &lt;unistd.h&gt;
#include &lt;stdlib.h&gt;

#define N_COUNTER 4 //공유 버퍼에 저장할 정수 공간의 개수
#define MILLI 1000

void mywrite(int n);
int myread();

pthread_mutex_t critical_section;
sem_t semWrite, semRead; //POSIX 세마포
int queue[N_COUNTER]; //공유버퍼
int wptr; //queue[]에 저장할 다음 인덱스
int rptr; //queue[]에서 읽을 다음 인덱스

void* producer(void* arg){ //생산자 스레드 함수
    for(int i = 0; i&lt;10; i++){
        mywrite(i); //정수 i를 공유버퍼에 저장
        printf(&quot;producer : wrote %d\n&quot;, i); 

        //m 밀리초 동안 잠을 잔다.
        int m = rand()%10; //0~9 사이의 랜덤한 정수
        usleep(MILLI*m*10); //m*10 밀리초동안 잠자기
    }
    return NULL;

}

void* consumer(void* arg){ //소비자 스레드 함수
    for(int i =0; i&lt;10; i++){
        int n = myread(); //공유버퍼의 맨 앞에 있는 정수 읽어 리턴
        printf(&quot;\tconsumer : read %\n&quot;, i);


        //m 밀리초동안 잠을 잔다
        int m = rand()%10; //0~9 사이의 랜덤한 정수
        usleep(MILLI*m*10); //m*10 밀리초동안 잠자기
    }
    return NULL;
}

void mywrite(int n){ //정수 n을 queue[]에 삽입
    sem_wait(&amp;semWrite); //queue[]에 쓸 수 있는지 요청

    pthread_mutex_lock(&amp;critical_section); //뮤텍스 락 잠그기
    queue[wptr] = n; //버퍼에 정수 n을 삽입
    wptr++;
    wptr% = N_COUNTER;
    pthread_mutex_unlock(&amp;critical_section); //뮤텍스 락 열기
}

int myread() { //queue[] 맨 앞에 있는 정수를 읽어 리턴
    sem_wait(&amp;semRead); //queue[]에서 읽을 수 있는지 요청

    pthread_mutex_lock(&amp;critical_section); //뮤텍스 락 잠그기
    int n = queue[rptr]; //버퍼에서 정수를 읽는다.
    rptr++;
    rptr %= N_COUNTER;
    pthread_mutex_unlock(&amp;critical_section); // producer 스레드 깨우기

    sem_post(&amp;semWrite);
    return n;
}

int main(){
    pthread_t t[2]; //스레드 구조체

    srand(time(NULL)); //난수 발생을 위한 seed 생성

    pthread_mutex_init(&amp;critical_section, NULL); //뮤텍스 락 초기화

    //세마포 초기화 : N_COUNTER 개의 자원으로 초기화
    sem_init(&amp;semWrite, 0, N_COUNTER); //가용버퍼의 개수를 N_COUNTER로 초기화
    sem_init(&amp;semRead, 0, 0); //가용버퍼의 개수를 0으로 초기화

    //producer와 consumer 스레드 생성
    pthread_create(&amp;t[0], NULL, producer, NULL); //생산자 스레드 생성
    pthread_create(&amp;t[1], NULL, consumer, NULL); //소비자 스레드 생성 

    for(int i = 0; i&lt;2; i++)
        pthread_join(t[i], NULL); //모든 스레드가 소멸할 때까지 대기

    sem_destroy(&amp;semRead); //세마포 기능 소멸
    sem_destroy(&amp;semWrite); //세마포 기능 소멸
    pthread_mutex_destroy(&amp;critical_section); //뮤텍스 락 소멸
    return 0;
}</code></pre><p><img src="https://velog.velcdn.com/images/passion_man/post/09790631-c36a-4f29-9e82-ddd9acc2dc5f/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/b8b574c1-b6e0-427f-ac12-e2d525fa757d/image.png" alt=""></p>
<p>이 글이 문제가 된다면 삭제하겠습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] 5. CPU 스케줄링]]></title>
            <link>https://velog.io/@passion_man/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-5.-CPU-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81</link>
            <guid>https://velog.io/@passion_man/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-5.-CPU-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81</guid>
            <pubDate>Mon, 30 May 2022 04:44:35 GMT</pubDate>
            <description><![CDATA[<h1 id="cpu-스케줄링-개요">CPU 스케줄링 개요</h1>
<h2 id="운영체제에서-일어나는-다양한-스케줄링">운영체제에서 일어나는 다양한 스케줄링</h2>
<ul>
<li>자원에 대한 스케줄링<ul>
<li>자원에 대한 경쟁이 있는 곳에는 경쟁자 중 하나 선택</li>
</ul>
</li>
<li>컴퓨터 시스템 여러 곳에서 발생</li>
</ul>
<p>컴퓨터 시스템 내 다양한 스케줄링</p>
<ul>
<li><p>작업 스케줄링</p>
<ul>
<li>배치시스템에서 대기 중인 배치 작업 중 메모리에 적재할 작업 결정</li>
</ul>
</li>
<li><p>CPU 스케줄링</p>
<ul>
<li>프로세스/스레드 중에 하나를 선택해서 CPU 할당</li>
<li>오늘날 CPU 스케줄링은 스레드 중 하나를 선택하는 스레드 스케줄링</li>
</ul>
</li>
<li><p>디스크 스케줄링</p>
<ul>
<li>디스크 장치 내에서 디스크 입출력 요청 중 하나 선택</li>
</ul>
</li>
<li><p>프린터 스케줄링</p>
<ul>
<li>프린팅 작업 중 하나 선택하여 프린터 할당<h2 id="다중프로그래밍과-스케줄링">다중프로그래밍과 스케줄링</h2>
</li>
</ul>
</li>
<li><p>다중프로그래밍의 도입 목적</p>
<ul>
<li>CPU 유휴시간 줄이기 -&gt; CPU 활용률 향상</li>
<li>프로세스가 I/O를 요청하면 다른 프로세스에게 CPU 할당</li>
</ul>
</li>
<li><p>다중프로그래밍과 함께 2가지 스케줄링 도입</p>
</li>
</ul>
<p>1) 작업 스케줄링</p>
<ul>
<li>디스크 장치로부터 메모리에 올릴 작업 선택</li>
<li>처음에 혹은 프로세스가 종료할 때마다 </li>
</ul>
<p>2) CPU 스케줄링</p>
<ul>
<li>메모리에 적재된 작업 중 CPU에 실행시킬 프로세스 선택</li>
</ul>
<h2 id="cpu-burst-와-io-burst">CPU burst 와 I/O burst</h2>
<ul>
<li><p>프로그램의 일반적 실행 특성</p>
<ul>
<li>CPU 연산 작업과 화면 출력, 키보드, 입력, 파일 입출력 등 I/O 작업 섞여 있음</li>
</ul>
</li>
<li><p>CPU burst</p>
<ul>
<li>프로그램 실행 중 CPU 연산이 연속적으로 실행되는 상황</li>
</ul>
</li>
<li><p>I/O burst</p>
<ul>
<li>프로그램 실행 중 I/O 장치의 입출력이 이루어지는 상황<h2 id="cpu-스케줄링의-정의와-목표">CPU 스케줄링의 정의와 목표</h2>
</li>
</ul>
</li>
<li><p>프로그램의 실행의 특징</p>
<ul>
<li>CPU burst -&gt; I/O burst -&gt; CPU burst -&gt; I/O burst ..</li>
<li>연산작업 - 입출력작업 - 연산작업 - 입출력작업</li>
</ul>
</li>
<li><p>CPU 스케줄링 : 실행 준비 상태의 스레드 중 하나를 선택하는 과정</p>
</li>
<li><p>CPU 스케줄링의 기준</p>
<ul>
<li>컴퓨터 시스템들은 기본 목표 외에 서로 다른 스케줄링 목표를 가질 수 있음</li>
</ul>
</li>
<li><p>스케줄링 알고리즘의 다양한 목표와 평가 기준★
1) CPU 활용률 - 전체 시간 중 CPU의 사용시간 비율 (운영체제 입장)
2) 처리율 - 단위 시간 당 처리하는 프로세스의 개수 (운영체제 입장)
3) 공평성 - CPU를 스레드들에게 공평하게 배분 (사용자 입장)</p>
<ul>
<li>시분할로 스케줄링</li>
<li>무한정 대기하는 기아 스레드가 생기지 않도록 스케줄링
4) 응답 시간 - 대화식 사용자의 경우, 명령에 응답하는데 걸리는 시간 (사용자 입장)
5) 대기 시간 - 스레드가 준비 큐에서 머무르는 시간 (운영체제와 사용자 입장)
6) 소요 시간 - 프로세스(스레드)가 컴퓨터 시스템에 도착한 후 완료될 때까지 걸린 시간 (사용자 입장) - 배치 처리 시스템에서 주된 스케줄링의 기준
7) 시스템 정책 우선 - 컴퓨터 시스템의 특별한 목적을 달성하기 위한 스케줄링 (운영체제 입장)</li>
<li>예 : 실시간 시스템에서는 스레드가 완료 시한 내에 이루어지도록 하는 정책</li>
<li>예 : 급여 시스템에서는 안전을 관리하는 스레드 우선 정책 등
8) 자원 활용률</li>
</ul>
</li>
</ul>
<h2 id="타임-슬라이스">타임 슬라이스</h2>
<ul>
<li>대부분 운영체제에서 하나의 스레드가 너무 오래 CPU를 사용하도록 허락하지 않음</li>
<li>타임 슬라이스와 스케줄링<ul>
<li>스케줄된 스레드에게 한 번 할당하는 CPU 시간</li>
<li>커널이 스케줄을 단행하는 주기 시간</li>
</ul>
</li>
<li>타이머 인터럽트의 도움을 받아 타임 슬라이스 단위로 CPU 스케줄링</li>
<li>현재 실행 중인 스레드 강제 중단, 준비 리스트에 삽입<ul>
<li>타임 퀀텀, 타임 슬롯이라고도 함<h1 id="cpu-스케줄링-기본">CPU 스케줄링 기본</h1>
<h2 id="cpu-스케줄링이-실행되는-4가지-상황★">CPU 스케줄링이 실행되는 4가지 상황★</h2>
1) 스레드가 시스템 호출 끝에 I/O를 요청하여 블록될 때</li>
</ul>
</li>
<li>스레드를 블록 상태로 만들고 스케줄링</li>
<li>CPU의 활용률 향상 목적</li>
</ul>
<p>2) 스레드가 자발적으로 CPU를 반환할 때</p>
<ul>
<li>yield() 시스템 호출 등을 통해 스레드가 자발적으로 CPU 반환</li>
<li>커널은 현재 스레드를 준비 리스트에 넣고, 새로운 스레드 선택</li>
<li>CPU의 자발적 양보</li>
</ul>
<p>3) 스레드의 타임슬라이스가 소진되어 타이머 인터럽트 발생</p>
<ul>
<li>균등한 CPU 분배 목적</li>
</ul>
<p>4) 더 높은 순위의 스레드가 요청한 입출력 작업 완료, 인터럽트 발생</p>
<ul>
<li>현재 스레드를 강제 중단시켜 준비 리스트에 넣고</li>
<li>높은 순위의 스레드를 깨워 스케줄링</li>
<li>우선순위를 지키기 위한 목적</li>
</ul>
<h2 id="cpu-스케줄링과-디스패치">CPU 스케줄링과 디스패치</h2>
<p>CPU 스케줄링 코드의 위치와 실행 시점</p>
<ul>
<li><p>스케줄링을 담당하는 커널 스레드나 프로세스는 없음</p>
</li>
<li><p>스케줄링 코드는 커널 내에 코드 형태로 위치</p>
<ul>
<li>스케줄링 코드는 커널 코드의 일부<ul>
<li>별도로 실행되는 프로세스나 스레드 형태가 아님</li>
<li>커널은 마치 응용프로그램을 컴파일(빌드) 하여 완성한 바이너리 모듈 같음, 메모리에 그대로 적재되는 한 덩어리의 바이너리</li>
</ul>
</li>
</ul>
</li>
<li><p>스케줄링 코드가 실행되는 시점</p>
<ul>
<li>시스템 호출이나 인터럽트 서비스 루틴이 끝나는 마지막 단계에서 실행</li>
</ul>
</li>
<li><p>디스패쳐 코드 실행</p>
</li>
<li><p>디스패쳐 코드 : 컨택스트 스위칭을 실행하는 커널 코드</p>
<ul>
<li>스케줄러에 의해 선택된 스레드를 CPU가 실행하도록 하는 작업</li>
<li>커널 모드에서 사용자 모드로 전환</li>
<li>새로 선택된 스레드가 이전에 중단된 곳에서 실행하도록 점프</li>
</ul>
</li>
</ul>
<p>** 스케줄러와 디스패쳐 모두 실행 시간이 짧도록 작성</p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/021b2559-816e-4f5d-8bbb-187a255d0ac3/image.png" alt=""></p>
<h2 id="선점-스케줄링과-비선점-스케줄링">선점 스케줄링과 비선점 스케줄링</h2>
<ul>
<li>실행 중인 스레드의 강제 중단 여부에 따른 CPU 스케줄링 타입</li>
</ul>
<p>1) 비선점 스케줄링</p>
<ul>
<li>현재 실행 중인 스레드를 강제로 중단시키지 않는 타입<ul>
<li>일단 스레드가 CPU를 할당받아 실행을 시작하면, 완료되거나 CPU를 더 이상 사용할 수 없는 상황이 될 때까지 스레드 강제 중단 시키지 않고 스케줄링도 하지 않는 방식</li>
</ul>
</li>
<li>스케줄링 시점<ul>
<li>CPU를 더 이상 사용할 수 없게 된 경우 : I/O 로 인한 블록 상태, sleep 등</li>
<li>자발적으로 CPU를 양보할 때</li>
<li>실행 중 종료할 때</li>
</ul>
</li>
</ul>
<p>2) 선점 스케줄링</p>
<ul>
<li>현재 실행 중인 스레드를 강제 중단 시키고 다른 스레드 선택, CPU 할당</li>
<li>스케줄링 시점<ul>
<li>타임슬라이스가 소진되어 타이머 인터럽트가 발생될 때</li>
<li>인터럽트나 시스템 호출 종료 시점에서, 더 높은 순위의 스레드가 준비 상태일 때</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/469faceb-87e2-42cc-b1fd-fdb545bc8257/image.png" alt=""></p>
<blockquote>
</blockquote>
<ul>
<li>비선점 스케줄링 <ul>
<li>이미 할당된 자원을 다른 프로세스가 강탈할 수 없음</li>
<li>응답시간의 예측이 편하며, 일괄처리 방식에 적합</li>
<li>단점으로는 덜 중요한 작업이 자원을 할당받으면 중요 작업이 와도 먼저 처리될 수 없음</li>
<li>FCFS(FIFO구조 알고리즘), SJF, HRN, 우선순위, 기한부<blockquote>
</blockquote>
</li>
</ul>
</li>
<li>선점 스케줄링<ul>
<li>우선순위가 높은 프로세스를 빠르게 처리할 수 있음</li>
<li>어떤 프로세스가 자원을 사용하고 있을 때 우선순위가 더 높은 프로세스가 올 경우 자원을 강탈함</li>
<li>빠른 응답 시간을 요구하는 시스템에서 사용</li>
<li>오버헤드가 크다</li>
<li>Round Robin, SRT, 선점 우선순위, 다단계 큐, 다단계 피드백큐</li>
</ul>
</li>
</ul>
<h2 id="기아와-에이징">기아와 에이징</h2>
<p>1) 기아</p>
<ul>
<li>스레드가 스케줄링에서 선택되지 못한 채 오랫동안 준비리스트에 있는 상황</li>
<li>사례<ul>
<li>우선순위를 기반으로 하는 시스템에서 더 높은 순위의 스레드가 계속 시스템에 들어오는 경우<ul>
<li>짧은 스레드를 우선 실행시키는 시스템에서, 자신보다 짧은 스레드가 계속 도착하는 경우<ul>
<li>스케줄링 알고리즘 설계 시 기아발생을 면밀히 평가</li>
</ul>
</li>
<li>기아가 발생하지 않도록 설계하는 것이 바람직함</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>2) 에이징</p>
<ul>
<li>기아의 해결책</li>
<li>스레드가 준비리스트에 머무는 시간에 비례하여 스케줄링 순위를 높이는 기법<ul>
<li>오래 기다릴 수는 있지만 언젠가는 가장 높은 순위에 도달하는 것을 보장<h1 id="cpu-스케줄링-알고리즘">CPU 스케줄링 알고리즘</h1>
<h2 id="다양한-cpu-스케줄링-알고리즘">다양한 CPU 스케줄링 알고리즘</h2>
1) FCFS(First come First served) - 비선점 스케줄링</li>
</ul>
</li>
<li>도착한 순서대로 스레드를 준비 큐에 넣고 도착한 순서대로 처리</li>
</ul>
<p>2) Shortest Job First - 비선점 스케줄링</p>
<ul>
<li>가장 짧은 스레드 우선 처리</li>
</ul>
<p>3) Shortest remaining time first - 선점 스케줄링</p>
<ul>
<li>남은 시간이 짧은 스레드가 준비 큐에 들어오면 이를 우선 처리</li>
</ul>
<p>4) Round - robin - preemptive </p>
<ul>
<li>스레드들을 돌아가면서 할당된 시간(타임슬라이스)만큼 실행</li>
</ul>
<p>5) Priority Scheduling - 선점/비선점 스케줄링 둘 다 구현 가능</p>
<ul>
<li>우선순위를 기반으로 하는 스케줄링. 가장 높은 순위의 스레드 먼저 실행</li>
</ul>
<p>6) Multilevel queue scheduling - 선점/비선점 스케줄링 둘 다 구현 가능</p>
<ul>
<li>스레드와 큐 모두 n개의 우선순위 레벨로 할당, 스레드는 자신의 레벨과 동일한 큐에 삽입</li>
<li>높은 순위의 큐에서 스레드 스케줄링, 높은 순위의 큐가 빌 때 아래 순위의 큐에서 스케줄링</li>
<li>스레드는 다른 큐로 이동하지 못함</li>
<li>예 : Background process, Foreground process</li>
</ul>
<p>7) Multilevel feedback queue scheduling - 선점/비선점 스케줄링 둘 다 구현 가능</p>
<ul>
<li>큐만 n개의 우선순위 레벨을 둠. 스레드는 레벨이 없이 동일한 우선 순위</li>
<li>스레드는 제일 높은 순위의 큐에 진입하고 큐타임슬라이스가 다하면 아래 레벨의 큐로 이동</li>
<li>낮은 레벨의 큐에 오래 있으면 높은 레벨의 큐로 이동</li>
</ul>
<blockquote>
</blockquote>
<p>[참고]</p>
<blockquote>
</blockquote>
<p>여러 개의 큐</p>
<blockquote>
</blockquote>
<ul>
<li>레디 큐를 여러 개로 분할 </li>
<li><blockquote>
<p>foreground </p>
</blockquote>
</li>
<li><blockquote>
<p>background </p>
</blockquote>
</li>
<li>각 큐는 독립적인 스케줄링 알고리즘을 가짐</li>
<li><blockquote>
<p>foreground - RR</p>
</blockquote>
</li>
<li><blockquote>
<p>background - FCFS</p>
</blockquote>
</li>
<li>큐에 대한 스케줄링이 필요<blockquote>
</blockquote>
</li>
<li>포그라운드 큐 : 사용자와 소통 중심
백그라운드 큐 : 배치 프로그램</li>
</ul>
<h2 id="fcfs">FCFS</h2>
<ul>
<li>선입선처리 알고리즘<ul>
<li>먼저 도착한 스레드 먼저 스케줄링</li>
</ul>
</li>
<li>스케줄링 파라미터 : 스레드 별 도착 시간</li>
<li>스케줄링 타입 : 비선점 스케줄링</li>
<li>스레드 우선 순위 : 없음</li>
<li>기아 : 발생하지 않음<ul>
<li>스레드가 오류로 인해 무한 루프를 실행한다면 뒤 스레드의 기아 발생</li>
</ul>
</li>
<li>성능 이슈<ul>
<li>처리율 : 낮음<ul>
<li>호위 효과 발생 : 긴 스레드가 CPU를 오래 사용하면, 늦게 도착하면 짧은 소레드는 오래 대기</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/0ad45b69-2776-47fd-a5f8-7ad85b23b07b/image.png" alt=""></p>
<h2 id="sjf">SJF</h2>
<ul>
<li><p>최단작업 우선 스케줄링 알고리즘</p>
<ul>
<li>예상 실행시간이 가장 짧은 스레드 선택<ul>
<li>스레드가 도착할 때, 예상 실행시간이 짧은 순으로 큐 삽입, 큐의 맨 앞에 있는 스레드 선택</li>
</ul>
</li>
</ul>
</li>
<li><p>스케줄링 파라미터 : 스레드 별 예상 실행 시간</p>
</li>
<li><p>스케줄링 타입 : 비선점 스케줄링</p>
</li>
<li><p>스레드 우선 순위 : 없음</p>
</li>
<li><p>기아 : 발생 가능</p>
<ul>
<li>지속적으로 짧은 스레드가 도착하면, 긴 스레드는 언제 실행 기회를 얻을지 예측할 수 없음</li>
</ul>
</li>
<li><p>성능 이슈</p>
<ul>
<li>짧은 스레드가 먼저 실행되므로 평균 대기 시간 최소화</li>
</ul>
</li>
<li><p>문제점</p>
<ul>
<li>실행 시간의 예측이 불가능하므로 현실에서는 거의 사용되지 않음</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/0b21ab26-c0fe-4b3b-99c2-0f661e2df933/image.png" alt=""></p>
<h2 id="srtf">SRTF</h2>
<ul>
<li>최소 잔여 시간 우선 스케줄링 알고리즘</li>
<li>남은 실행 시간이 가장 짧은 스레드 선택</li>
<li>SJF의 선점 스케줄링 버전<ul>
<li>실행시간이 짧은 순으로 스레드들을 큐에 삽입, 한 스레드가 끝나거나 실행시간이 더 짧은 스레드가 도착할 때, 가장 짧은 스레드 선택<ul>
<li>큐의 맨 앞에 있는 스레드 선택</li>
</ul>
</li>
</ul>
</li>
<li>스케줄링 파라미터 : 스레드 별 예상 실행 시간과 남은 실행 시간 값<ul>
<li>이 시간을 아는 것은 불가능. 비현실적</li>
</ul>
</li>
<li>스케줄링 타입 : 선점 스케줄링</li>
<li>스레드 우선 순위 : 없음</li>
<li>기아 : 발생 가능<ul>
<li>지속적으로 짧은 스레드가 도착하는 경우 긴 스레드는 언제 실행 기회를 얻을 수 있을지 예상할 수 없음</li>
</ul>
</li>
<li>성능 이슈 <ul>
<li>실행 시간이 짧은 프로세스가 먼저 실행되므로 평균 대기 시간 최소화</li>
</ul>
</li>
<li>문제점 <ul>
<li>실행 시간 예측이 불가능하므로  현실에서는 거의 사용되지 않음</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/f31ea910-9126-44b3-8b13-07b596bc039b/image.png" alt=""></p>
<h2 id="rr">RR</h2>
<ul>
<li>스레드들에게 공평한 실행 기회를 주기 위해 큐에 대기중인 스레드들을 타임 슬라이스 주기로 돌아가면서 선택하는 알고리즘</li>
<li>도착하는 순서대로 스레드들을 큐에 삽입</li>
<li>타임 슬라이스가 지나면 큐 끝으로 이동</li>
<li>스케줄링 파라미터 : 타임 슬라이스</li>
<li>스케줄링 타입 : 선점 스케줄링</li>
<li>스레드 우선 순위 : 없음</li>
<li>기아 : 없음<ul>
<li>스레드의 우선순위가 없고, 타임 슬라이스가 정해져 있어, 일정 시간 후에 스레드는 반드시 실행</li>
</ul>
</li>
<li>성능 이슈<ul>
<li>공평하고, 기아현상 없고, 구현이 쉬움<ul>
<li>잦은 스케줄링으로 전체 스케줄링 오버헤드가 큼. 특히 타임슬라이스가 작을 때 더욱 큼</li>
<li>균형된 처리율 : 타임슬라이스가 크면 FCFS에 가까움, 작으면 SJF/SRTF 에 가까움</li>
</ul>
</li>
<li>늦게 도착한 짧은 프로세는 FCFS보다 빨리 완료되고, 긴 프로세스는 SJF보다 빨리 완료됨</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/d348e7ab-d87f-434e-a589-7e0992191a94/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/04e05bf1-4b22-410a-99e7-47b5888e972a/image.png" alt=""></p>
<h2 id="priority-스케줄링">Priority 스케줄링</h2>
<ul>
<li>우선순위에 따라 스레드들 실행시키기 위한 목적인 알고리즘</li>
<li>가장 높은 순위의 스레드 선택<ul>
<li>현재 스레드가 종료되거나 더 높은 순위의 스레드가 도착할 때, 가장 높은 순위의 스레드 선택<ul>
<li>모든 스레드에 고정 우선 순위 할당, 종료 때까지 바뀌지 않음</li>
<li>도착하는 스레드는 우선순위 순으로 큐에 삽입</li>
</ul>
</li>
</ul>
</li>
<li>스케줄링 파라미터 : 선점/비선점 스케줄링<ul>
<li>선점 스케줄링 : 더 높은 스레드가 도착할 때 현재 스레드 강제 중단하고 스케줄링<ul>
<li>비선점 스케줄링 : 현재 실행 중인 스레드가 종료될 때 비로소 스케줄링</li>
</ul>
</li>
</ul>
</li>
<li>스레드 우선 순위 : 있음</li>
<li>기아 : 발생 가능<ul>
<li>지속적으로 높은 순위의 스레드가 도착하는 경우 언제 실행 기회를 얻을 수 있을지 예상할 수 없음<ul>
<li>큐 대기 시간에 비례하여 일시적으로 우선순위를 높이는 에이징 방법으로 해결 가능</li>
</ul>
</li>
</ul>
</li>
<li>성능 이슈<ul>
<li>높은 우선순위의 스레드일 수록 대기 혹은 응답시간 짧음</li>
</ul>
</li>
<li>특징<ul>
<li>스레드 별 고정 우선 순위를 가지는 실시간 시스템에서 사용 </li>
</ul>
</li>
</ul>
<h2 id="mlq">MLQ</h2>
<ul>
<li>설계 의도 : 스레드들을 n개의 우선순위 레벨로 구분, 레벨이 높은 스레드들을 우선적으로 처리하는 목적</li>
<li>알고리즘<ul>
<li>고정된 n 개의 큐 사용, 각 큐에 고정 우선순위 할당<ul>
<li>각 큐는 나름대로의 기법으로 스케줄링</li>
<li>스레드는 도착 시 우선 순위에 따라 해당 레벨 큐에 삽입. 다른 큐로 이동할 수 없음</li>
<li>가장 높은 순위의 큐가 빌 때, 그 다음 순위의 큐에서 스케줄링</li>
</ul>
</li>
</ul>
</li>
<li>스케줄링 파라미터 : 스레드의 고정 우선순위</li>
<li>스케줄링 타입 : 비선점/선점 모두 가능<ul>
<li>비선점 스케줄링 : 현재 실행중인 스레드가 종료할 때 비로소 스케줄링<ul>
<li>선점 스케줄링 : 높은 레벨의 큐에 스레드가 도착하면 중단하고 높은 순위의 레벨 큐에서 스케줄링</li>
</ul>
</li>
</ul>
</li>
<li>기아 : 발생 가능<ul>
<li>지속적으로 높은 순위의 스레드가 도착하는 경우 언제 실행 기회를 얻을 수 있을지 예상할 수 없음</li>
</ul>
</li>
<li>성능 이슈와 활용 사례<ul>
<li>스레드의 고정 순위를 가진 시스템에서 활용<ul>
<li>예 : 전체 스레드를 백그라운드 스레드와 포그라운드 스레드의 2개의 그룹을 구성</li>
<li>예 : 시스템 스레드, 대화식 스레드, 배치 스레드 등 3개의 레벨로 나누고 시스템 스레드를 우선적으로 스케줄링</li>
<li>예 : 대학에서 교수, 교직원 , 대학원생, 학부생 등 사용자를 4개의 레벨로 나누고, 사용자에 따라 실행시킨 스레드 레벨로 스케줄링</li>
</ul>
</li>
</ul>
</li>
</ul>
<blockquote>
</blockquote>
<p>[참고]</p>
<blockquote>
</blockquote>
<ul>
<li>MLF 스케줄링</li>
<li><blockquote>
<p>FIFO + RR 스케줄링</p>
</blockquote>
</li>
<li><blockquote>
<p>작업을 전면 작업(대화형, foreground task) 과 후면 작업(일괄처리형, background task) 로 분류한다면 두 유형의 반응 시간이 다르므로 서로 다르게 스케줄링 해야한다. </p>
</blockquote>
</li>
<li><blockquote>
<p>전면 작업은 후면 작업에 비해 높은 우선순위를 갖는 경우가 많다.
예를 들어, 쇼핑몰에서 쇼핑은 빠르게 백그라운드에서 다운로드는 느리게 </p>
</blockquote>
</li>
</ul>
<h2 id="mlfq">MLFQ</h2>
<ul>
<li><p>설계 의도</p>
<ul>
<li>1962년에 개발된 알고리즘<ul>
<li>기아를 없애기 위해 여러 레벨의 큐 사이에 스레드 이동 가능하도록 설계</li>
<li>짧은 스레드와 I/O가 많은 스레드, 대화식 스레드의 우선처리. 스레드 평균대기시간 줄임</li>
</ul>
</li>
</ul>
</li>
<li><p>n개의 레벨 큐</p>
<ul>
<li>n개의 고정 큐. 큐마다 서로 다른 스케줄링 알고리즘<ul>
<li>큐마다 스레드가 머무를 수 있는 큐타임 슬라이스가 있음. 낮은 레벨의 큐일 수록 더 긴 타임 슬라이스</li>
<li>I/O 집중 스레드(대화식 스레드)는 높은 순위의 큐에 있을 가능성이 높음</li>
</ul>
</li>
</ul>
</li>
<li><p>알고리즘</p>
<ul>
<li>스레드는 도착 시 최상위 레벨의 큐에 삽입<ul>
<li>가장 높은 레벨의 큐에서 스레드 선택. 비어 있으면 그 아래의 큐에서 스레드 선택</li>
<li>스레드의 CPU-burst가 큐 타임 슬라이스를 초과하면 강제로 아래 큐로 이동 시킴</li>
<li>스레드가 자발적으로 중단한 경우, 현재 큐의 끝에 삽입</li>
<li>스레드가 I/O로 실행이 중단된 겨웅, I/O가 끝나면 동일한 레벨 큐 끝에 삽입</li>
<li>큐에 있는 시간이 오래되면 기아를 막기 위해 하나의 위 레벨 큐로 이동</li>
<li>최하위 레벨 큐는 주로 FCFS나 긴 타임 슬라이스의 RR로 스케줄. 스레드들은 다른 큐로 이동 못함</li>
</ul>
</li>
</ul>
</li>
<li><p>스케줄링 파라미터 : 각 큐의 큐 시간 할당량</p>
</li>
<li><p>스케줄링 타입 : 선점 스케줄링</p>
</li>
<li><p>스레드 우선 순위 : 없음</p>
</li>
<li><p>기아 : 발생하지 않음. 큐에 대기하는 시간이 오래되면 더 높은 레벨의 큐로 이동시킴(에이징 기법)</p>
</li>
<li><p>성능 이슈</p>
<ul>
<li>짧거나 입출력이 빈번한 스레드, 혹은 대화식 스레드를 높은 레벨의 큐에서 빨리 실햄 -&gt; CPU 활용률이 높음</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/61e1e471-f3f1-4003-b88d-a9902f5900c5/image.png" alt=""></p>
<h1 id="멀티코어-cpu에서의-스케줄링">멀티코어 CPU에서의 스케줄링</h1>
<h2 id="멀티코어-시스템의-구조">멀티코어 시스템의 구조</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/4847490c-7356-4515-a70f-f089f708601e/image.png" alt=""></p>
<h2 id="멀티코어-시스템에서의-멀티스레딩">멀티코어 시스템에서의 멀티스레딩</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/8d21752e-4a9e-4e12-873e-527d976c0a89/image.png" alt=""></p>
<h2 id="멀티코어-시스템에서의-cpu-스케줄링">멀티코어 시스템에서의 CPU 스케줄링</h2>
<ul>
<li>멀티코어 시스템에서 싱글코어 CPU의 스케줄링을 사용할 때 문제점</li>
</ul>
<p>1) 컨텍스트 스위칭 오버헤드 증가문제</p>
<ul>
<li><p>이전에 실행된 적이 없는 코어에 스레드가 배치될 때</p>
</li>
<li><p>캐시에 새로운 스레드의 코드와 데이터로 채워지는 긴 경과 시간</p>
</li>
<li><p>해결</p>
<ul>
<li>CPU 친화성 (CPU affinity) 적용<ul>
<li>스케드를 동일한 코어에서만 실행하도록 스케줄링</li>
<li>코어 친화성 (Core affinity), CPU 피닝(pinning), 캐시 친화성(cache affinity) 라고도 부름</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>2) 코어별 부하 불균형 문제</p>
<ul>
<li><p>스레드를 무작위로 코어에 할당하면, 코어마다 처리할 스레드 수의 불균형 발생</p>
</li>
<li><p>해결 </p>
<ul>
<li>부하 불균등 기법으로 해결<ul>
<li>푸시 마이그레이션 : 감시 스레드가 짧거나 빈 큐를 가진 코어에 다른 큐의 스레드를 옮겨놓는 기법</li>
<li>풀 마이그레이션 : 코어가 처리할 스레드가 없게 되면, 다른 코어의 스레드 큐에서 자신이 큐에 가져와 실행시키는 기법</li>
</ul>
</li>
</ul>
</li>
</ul>
<blockquote>
</blockquote>
<p>** 여러가지 스케줄링 기법 Youtube로 찾아보고 더 자세히 이해하기 </p>
<p>이 글이 문제가 된다면 삭제하겠습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] 4. 스레드와 멀티태스킹]]></title>
            <link>https://velog.io/@passion_man/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-4.-%EC%8A%A4%EB%A0%88%EB%93%9C%EC%99%80-%EB%A9%80%ED%8B%B0%ED%83%9C%EC%8A%A4%ED%82%B9</link>
            <guid>https://velog.io/@passion_man/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-4.-%EC%8A%A4%EB%A0%88%EB%93%9C%EC%99%80-%EB%A9%80%ED%8B%B0%ED%83%9C%EC%8A%A4%ED%82%B9</guid>
            <pubDate>Mon, 30 May 2022 04:43:19 GMT</pubDate>
            <description><![CDATA[<h1 id="프로세스의-문제점">프로세스의 문제점</h1>
<h2 id="프로세스의-문제점-1">프로세스의 문제점</h2>
<p>1) 프로세스 생성의 큰 오버헤드</p>
<ul>
<li>프로세스 생성<ul>
<li>프로세스를 위한 메모리 할당 - 부모프로세스로부터 복사</li>
<li>PCB 생성, 매핑 테이블(페이지 테이블) 생성 등</li>
</ul>
</li>
</ul>
<p>2) 프로세스 컨텍스트 스위칭의 큰 오버헤드</p>
<ul>
<li>컨텍스트 스위칭<ul>
<li>CPU가 참고할 매핑 테이블(페이지 테이블) 전화네 따른 지연 시간 등</li>
<li>CPU 레지스터들을 프로세스 컨텍스트에 저장, 새 프로세스 컨텍스트를 CPU로 옮기는 시간</li>
<li>CPU 캐시에 새로운 프로세스의 코드와 데이터가 채워지는데 걸리는 시간 등</li>
</ul>
</li>
</ul>
<p>3) 프로세스 사이 통신의 어려움</p>
<ul>
<li><p>프로세스들은 완전한 독립적인 주소 공간을 가지고 있음</p>
<ul>
<li>프로세스가 다른 프로세스의 메모리에 접근 불가</li>
</ul>
</li>
<li><p>프로세스 사이의 통신을 위한 제3의 방법 필요</p>
<ul>
<li>커널 메모리나 커널에 의해 마련된 메모리 공간을 이용하여 데이터 송수신 (신호, 소켓, 메시지 큐, 세마포, 공유메모리, 메모리맵 파일 등)</li>
<li>이 방법들은 코딩도 어렵고, 느린 실행 속도, 운영체제 호환성 부족<h1 id="스레드의-개념">스레드의 개념</h1>
<h2 id="스레드의-출현-목적">스레드의 출현 목적</h2>
</li>
</ul>
</li>
<li><ul>
<li>프로세스를 사용하는 문제점 해결을 위해 고안</li>
</ul>
</li>
<li><p>프로세스보다 더 작은 실행 단위 필요</p>
<ul>
<li>실행 단위란 운영체제의 스케줄링 단위</li>
<li>스레드를 가벼운 프로세스(light- weight process, LWP)라고 부름</li>
</ul>
</li>
<li><p>프로세스의 생성 및 소멸에 따른 오버헤드 감소</p>
</li>
<li><p>빠른 컨텍스트 스위칭</p>
</li>
<li><p>프로세스의 복잡한 통신 방법, 느린 실행 속도, 코딩의 어려움 해소</p>
<h2 id="프로세스와-스레드-관리">프로세스와 스레드 관리</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/fea556e6-18f3-4a1d-8f82-47cf7f2320ec/image.png" alt=""></p>
</li>
</ul>
<h2 id="멀티스레딩과-concurrency-parallelism">멀티스레딩과 concurrency, parallelism</h2>
<p>concurrency(동시성)</p>
<ul>
<li>1개의 CPU에서 2개 이상의 스레드가 동시에 실행 중인 상태<ul>
<li>입출력 때문에 중단하면 다른 스레드 실행</li>
<li>타임 슬라이스 단위로 CPU를 사용하도록 번갈아 스레드 실행
<img src="https://velog.velcdn.com/images/passion_man/post/3cca19fe-7d40-4a3b-af29-b7851b706e92/image.png" alt="">
parallelism</li>
</ul>
</li>
<li>2개 이상의 스레드가 다른 CPU에서 같은 시간에 동시에 실행 (멀티코어)
<img src="https://velog.velcdn.com/images/passion_man/post/6da23abb-358b-4dc7-8ad1-99fce8f73fbd/image.png" alt=""></li>
</ul>
<h1 id="스레드-주소공간과-컨텍스트">스레드 주소공간과 컨텍스트</h1>
<h2 id="스레드-주소공간">스레드 주소공간</h2>
<p>스레드 주소 공간
-스레드가 생성되고 실행되는 동안 접근 가능한 메모리 영역</p>
<ul>
<li><p>스레드 주소 공간은 프로세스의 주소 공간 내에 형성</p>
</li>
<li><p>스레드 주소 공간을 구성하는 요소들</p>
</li>
<li><p>스레드 사적 공간</p>
</li>
<li><p>스레드 코드</p>
<ul>
<li>스레드 로컬 스토리지 (TLS, Threead local storage)</li>
</ul>
</li>
<li><p>스레드 사이의 공유 공간 (프로세스 내에 있음)</p>
<ul>
<li>프로세스의 코드</li>
<li>프로세스의 데이터 공간(로컬 스토리지 제외)</li>
<li>프로세스의 힙 영역
<img src="https://velog.velcdn.com/images/passion_man/post/1dec6272-d53a-4cc8-8077-952948aaa1d3/image.png" alt=""></li>
</ul>
</li>
</ul>
<p>1) 스레드 코드 영역</p>
<ul>
<li>스레드가 실행할 작업의 함수<ul>
<li>프로세스의 코드 영역 사용</li>
</ul>
</li>
<li>스레드는 프로세스의 코드 영역에 있는 다른 모든 함수 호출 가능</li>
</ul>
<p>2) 스레드 데이터 영역</p>
<ul>
<li>스레드가 사용할 수 있는 데이터 공간<ul>
<li>프로세스의 데이터 영역으로 사용</li>
</ul>
</li>
<li>2개의 공간으로 구분<ul>
<li>개별 스레드 전용 전역 변수 공간 (스레드 로컬 스토리지) - static __thread 와 같은 특별한 키워드로 선언, 컴파일러에 의해 결정</li>
<li>프로세스에 선언된 모든 전역 변수들은 모든 스레드에 의해 공유</li>
<li>스레드 사이의 통신 공간으로 유용하게 사용</li>
</ul>
</li>
</ul>
<p>3) 스레드 힙</p>
<ul>
<li>모든 스레드가 동적 할당 받는 공간, 프로세스의 힙 공간 사용</li>
<li>스레드에서 malloc()를 호출하면 프로세스의 힙공간에서 할당받음</li>
</ul>
<p>4) 스레드 스택</p>
<ul>
<li><p>스레드가 생성될 때마다 프로세스의 사용자 스택의 일부분 할당</p>
</li>
<li><p>스레드가 시스템 호출로 커널에 진입할 때, 커널 내에 스레드를 위한 스택 생성 (커널 스택이라고 부름)</p>
<h2 id="스레드-상태">스레드 상태</h2>
</li>
<li><p>스레드 일생</p>
<ul>
<li>생성, 실행, 중단, 실행, 소멸의 여러 상태를 거치는 스레드 인생</li>
<li>스레드 상태는 TCB에 저장</li>
<li>스레드 상태
1) 준비 상태(Ready) - 스레드가 스케줄 되기를 기다리는 상태
2) 실행 상태(Running) - 스레드가 CPU에 의해 실행 중인 상태
3) 대기 상태(Blocked) - 스레드가 입출력을 요청하거나 sleep()과 같은 시스템 호출로 인해 커널에 의해 중단된 상태
4) 종료 상태(Terminated) - 스레드가 종료된 상태
<img src="https://velog.velcdn.com/images/passion_man/post/60f7b9a2-c3bf-4cfc-b111-6fc65e7154c7/image.png" alt=""></li>
</ul>
</li>
</ul>
<h2 id="스레드-운용">스레드 운용</h2>
<p>응용프로그램이 스레드에 대해 할 수 있는 운용의 종류</p>
<p>1) 스레드 생성</p>
<ul>
<li>스레드는 스레드를 생성하는 시스템 호출이나 라이브러리 함수를 호출하여 다른 스레드 생성 가능</li>
<li>프로세스가 생성되면 자동으로 main 스레드 생성</li>
</ul>
<p>2) 스레드 종료</p>
<ul>
<li>프로세스 종료와 스레드 종료 구분 필요</li>
<li>프로세스 종료</li>
</ul>
<blockquote>
</blockquote>
<p>프로세스에 속한 어떤 스레드라도 exit() 시스템 호출을 부르면 프로세스 종료( 모든 스레드 종료 )
메인 스레드의 종료(C프로그램에서 main() 함수 종료) - 모든 스레드도 함께 종료
모든 스레드가 종료하면 프로세스 종료 -&gt; 스레드 종료</p>
<p>pthread_exit() 과 같이 스레드만 종료하는 함수 호출 시 해당 스레드만 종료
main() 함수에서 pthread_exit()을 부르면 역시 main 스레드만 종료</p>
<ul>
<li><p>스레드 조인</p>
</li>
<li><p>스레드가 다른 스레드가 종료할 때까지 대기</p>
<ul>
<li>주로 부모 스레드가 자식 스레드의 종료 대기</li>
</ul>
</li>
<li><p>스레드 양보</p>
</li>
<li><p>스레드가 자발적으로 yield() 와 같은 함수 호출을 통해 자신의 실행을 중단하고 다른 스레드를 스케줄하도록 지시</p>
</li>
</ul>
<h2 id="스레드-컨텍스트">스레드 컨텍스트</h2>
<p>1) 스레드 컨텍스트</p>
<ul>
<li>스레드의 실행중인 상태 정보<ul>
<li>CPU 레지스터들의 값</li>
<li>PC, SP, 데이터/상태 레지스터 등</li>
<li>TCB에 저장됨</li>
</ul>
</li>
</ul>
<p>2) PC 레지스터</p>
<ul>
<li>실행 중인 코드 주소</li>
</ul>
<p>2) SP 레지스터</p>
<ul>
<li>실행 중인 함수의 스택 주소</li>
</ul>
<p>3) 상태 레지스터</p>
<ul>
<li>현재 CPU의 상태 정보</li>
</ul>
<p>4) CPU에는 수십 개의 레지스터</p>
<ul>
<li>이들만 저장해두었다가 필요할 때 CPU에 복귀하면</li>
<li>이전에 실행하던 상태로 돌아갈 수 있음</li>
</ul>
<h2 id="스레드-제어블록">스레드 제어블록</h2>
<p>스레드 제어블록, TCB :스레드를 실행 단위로 다루기 위해 스레드에 관한 정보를 담은 구조체</p>
<ul>
<li>스레드 엔터디, 스케줄링 엔터티 라고도 불림</li>
<li>커널 영역에 만들어지고, 커널에 의해 관리<ul>
<li>스레드가 생성될 때 커널에 의해 만들어짐</li>
<li>스레드가 소멸되면 함께 사라짐</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/d6312715-f3e4-49fd-8ee1-5707167d0e98/image.png" alt=""></p>
<h2 id="스레드와-tcb-그리고-pcb의-관계">스레드와 TCB, 그리고 PCB의 관계</h2>
<ul>
<li>프로세스 : 스레드들이 생기고 활동하는 자원의 컨테이너</li>
<li>TCB : 링크드 리스트로 연결<h2 id="준비리스트와-블록리스트">준비리스트와 블록리스트</h2>
1) 준비리스트</li>
<li>준비 상태의 스레드들의 TCB를 연결하여 관리하는 링크드 리스트</li>
<li>스레드 스케줄링은 준비 리스트의 TCB 중에서 하나 선택</li>
</ul>
<p>2) 블록리스트</p>
<ul>
<li>블록 상태의 스레드들의 TCB를 연결하여 관리하는 링크드 리스트<h1 id="스레드-컨텍스트-스위칭">스레드 컨텍스트 스위칭</h1>
<h2 id="스레드-컨텍스트-스위칭-1">스레드 컨텍스트 스위칭</h2>
스레드 컨텍스트 스위칭</li>
<li>현재 실행중인 스레드를 중단시키고, 다른 스레드에게 CPU 할당<ul>
<li>스레드 스위칭이라고도 부름</li>
<li>현재 CPU 컨텍스트를 TCB에 저장하고, 다른 TCB에 저장된 컨텍스트를 CPU에 적재<h2 id="스레드-스위칭이-발생하는-4가지-경우">스레드 스위칭이 발생하는 4가지 경우</h2>
스레드 스위칭이 발생하는 4가지 경우</li>
</ul>
</li>
</ul>
<ol>
<li>스레드가 자발적으로 다른 스레드에게 양보</li>
</ol>
<ul>
<li>yield() 등의 시스템 호출(혹은 라이브러리 호출) 을 통해</li>
</ul>
<ol start="2">
<li>스레드가 시스템 호출을 실행하여 블록되는 경우</li>
</ol>
<ul>
<li>read(), sleep(), wait() 등 I/O 가 발생하거나 대기할 수 밖에 없는 경우</li>
</ul>
<ol start="3">
<li>스레드의 타임 슬라이스를 소진한 경우</li>
</ol>
<ul>
<li>타이머 인터럽트에 의해 체크</li>
</ul>
<ol start="4">
<li>I/O 장치로부터 인터럽트가 발생한 경우</li>
</ol>
<ul>
<li>현재 실행 중인 스레드보다 더 높은 우선순위의 스레드가 I/O 작업을 끝낸 경우 등</li>
</ul>
<p>** 상황에 따라 운영체제에 따라 이들 4가지 경우에도 스레드 스위칭이 일어날 수도 있고 아닐 수도 있음</p>
<h2 id="스레드-스위칭이-발생하는-위치">스레드 스위칭이 발생하는 위치</h2>
<ul>
<li>스레드 스위칭이 이루어지는 위치는 2가지
1) 프로세스가 시스템 호출을 하여, 커널이 시스템 호출을 처리하는 과정에서
2) 인터럽트가 발생하여 인터럽트 서비스 루틴이 실행되는 도중 커널 코드에서<h2 id="스레드-스위칭-과정">스레드 스위칭 과정</h2>
1) CPU 레지스터 저장 및 복귀</li>
<li>현재 실행 중인 스레드 A의 컨텍스트를 TCB-A에 저장</li>
<li>TCB-B 에 저장된 스레드 B의 컨텍스트를 CPU에 적재<ul>
<li>CPU는 스레드가 B가 이전에 중단된 위치에서 실행 재개 가능</li>
<li>SP 레지스터를 복귀함으로서 자신의 이전 스택을 되찾게 됨</li>
</ul>
</li>
</ul>
<p>** 스택에는 이전 중단될 때 실행하던 함수의 매개변수나 지역변수들이 그대로 저장되어 있음</p>
<p>2) 커널 정보 수정</p>
<ul>
<li><p>TCB-A와 TCB-B에 스레드 상태 정보와 CPU 사용 시간 등 수정</p>
</li>
<li><p>TCB-A를 준비 리스트나 블록 리스트로 옮김</p>
</li>
<li><p>TCB -B를 준비 리스트에서 분리</p>
<h2 id="컨텍스트-스위칭-오버헤드">컨텍스트 스위칭 오버헤드</h2>
</li>
<li><p>컨텍스트 스위칭에는 어떤 부담(오버헤드)이 있는가?</p>
<ul>
<li>컨텍스트 스위칭은 모두 CPU작업 -&gt; CPU 시간 소모</li>
<li>컨텍스트 스위칭의 시간이 길어나, 잦은 경우 컴퓨터 처리율 저하</li>
</ul>
</li>
<li><p>구체적인 컨텍스트 스위칭 오버헤드</p>
<ul>
<li>동일한 프로세스의 다른 스레드로 스위칭되는 경우</li>
</ul>
</li>
<li><p>컨텍스트 저장 및 복귀</p>
<ul>
<li>현재 CPU의 컨텍스트(PC, SP, 레지스터) TCB에 저장</li>
<li>TCB로부터 스레드 컨텍스트를 CPU에 복귀</li>
<li>TCB 리스트 조작</li>
<li>캐시 플러시와 채우기 시간</li>
</ul>
</li>
<li><p>다른 프로세스의 스레드로 스위칭하는 경우</p>
<ul>
<li>다른 프로세스로 교체되면, CPU가 실행하는 주소 공간이 바뀌는 큰 변화로 인한 추가적인 오버헤드 발생</li>
<li>추가적인 메모리 오버헤드</li>
</ul>
</li>
<li><p>시스템 내에 현재 실행 중인 프로세스의 매핑 테이블을 새로운 프로세스의 매핑 테이블로 교체</p>
<ul>
<li>추가적인 캐시 오버헤드</li>
</ul>
</li>
</ul>
<p>** 프로세스가 바뀌기 때문에, CPU 캐시에 담긴 코드와 데이터 무력화
새 프로세스의 스레드가 실행을 시작하면 CPU 캐시 미스 발생, 캐시가 채워지는데 상당한 시간 소요</p>
<h1 id="커널-레벨-스레드와-사용자-레벨-스레드">커널 레벨 스레드와 사용자 레벨 스레드</h1>
<h2 id="커널-레벨-스레드와-사용자-레벨-스레드-1">커널 레벨 스레드와 사용자 레벨 스레드</h2>
<ul>
<li>스레드의 스케줄링 주체에 따라 2종류의 스레드로 구분
1) 커널 레벨 스레드 : 커널에 의해 스케줄링되는 스레드
2) 사용자 레벨 스레드 : 스레드 라이브러리에 의해 스케줄링되는 스레드</li>
</ul>
<p>1) 커널레벨 스레드</p>
<ul>
<li>응용프로그램이 시스템 호출을 통해 커널 레벨 스레드 생성</li>
<li>커널이 스레드에 대한 정보(TCB)를 커널 공간에 생성하고 소유</li>
<li>커널에 의해 스케줄</li>
<li>스레드 주소 공간(스레드 코드와 데이터) : 사용자 공간에 존재</li>
<li>main 스레드는 커널 스레드<ul>
<li>응용프로그램이 적재되어 프로세스가 생성될 때 자동으로 커널은 main 스레드 생성</li>
</ul>
</li>
</ul>
<p>2) 사용자레벨 스레드</p>
<ul>
<li>응용프로그램이 라이브러리 함수를 호출하여 사용자 레벨 스레드 생성</li>
<li>스레드 라이브러리가 스레드 정보(U-TCB)를 사용자 공간에 생성하고 소유<ul>
<li>스레드 라이브러리는 사용자 공간에 존재</li>
<li>커널은 사용자 레벨 스레드의 존재에 대해 알 수 없음</li>
</ul>
</li>
<li>스레드 라이브러리에 의해 스케줄</li>
<li>스레드 주소 공간(스레드 코드와 데이터) : 사용자 공간에 존재</li>
</ul>
<p>3) 순수 커널레벨 스레드</p>
<ul>
<li>부팅 때부터 커널의 기능을 돕기 위해 만들어진 스레드</li>
<li>커널 코드를 실행하는 커널 스레드</li>
<li>스레드의 주소 공간은 모두 커널 공간에 형성</li>
<li>커널 모드에서 작동, 사용자 모드에서 실행되는 일은 없음
<img src="https://velog.velcdn.com/images/passion_man/post/d216aa2a-2a04-4a9e-90b6-032aa271f818/image.png" alt=""></li>
</ul>
<p>1) 2개의 순수 커널 레벨 스레드</p>
<ul>
<li>TCB1, TCB2</li>
<li>이들 스레드의 주소 공간은 커널에 있음.</li>
</ul>
<p>2) 2개의 커널 레벨 스레드</p>
<ul>
<li>프로세스 당 하나의 커널 레벨 스레드 (main 스레드) 자동 생성</li>
<li>TCB3<ul>
<li>커널은 단일 스레드 프로세스1을 적재할 때 자동으로 main 스레드 TCB3 생성</li>
<li>커널이 프로세스를 실행시키기 위함</li>
</ul>
</li>
<li>TCB4<ul>
<li>커널은 멀티스레드 프로세스2를 적재할 때 자동으로 main 스레드 TCB4 생성</li>
<li>커널이 프로세스를 실행시키기 위함</li>
</ul>
</li>
<li>TCB3와 TCB4의 스레드 주소 공간은 모두 사용자 공간에 있음</li>
</ul>
<p>3) 3개의 사용자 레벨 스레드</p>
<ul>
<li>멀티스레드 프로세스2의 main() 함수가 라이브러리 함수를 호출하여 자신을 사용자 레벨 스레드로 등록<ul>
<li>U-TCB1 생성</li>
</ul>
</li>
<li>멀티스레드 프로세스2의 main() 함수가 라이브러리 함수를 호출하여 2개의 사용자 레벨 스레드 추가 생성<ul>
<li>U-TCB2, U-TCB3 생성</li>
</ul>
</li>
</ul>
<p>4) 스레드 스케줄링</p>
<ul>
<li>커널에 의한 스케줄<ul>
<li>코어1 : TCB2 실행 (TCB2가 가리키는 커널 스레드 코드 2 실행)</li>
<li>코어2 : TCB4 실행 (TCB4가 가리키는 프로세스 내의 코드 실행)</li>
</ul>
</li>
</ul>
<p>** 처음에는 main() 함수에서 실행되지만, 어떤 함수인지 알 수 없음
커널은 프로세스 내에 하나의 스레드만 있다고 생각함</p>
<p>5) 멀티스레드 프로세스2에서의 사용자 스레드 스케줄링</p>
<ul>
<li><p>스레드 라이브러리가 3개의 사용자 스레드 스케줄</p>
</li>
<li><p>예 : main() 함수가 스레드 라이브러리의 yield() 함수를 호출하면 이 함수는 현재 대기중인 U-TCB2, U-TCB3 중에서 하나를 선택한다. 만약 U-TCB3가 선택되었다면, U-TCB1에 현재 실행 주소 등을 저장해두고, U-TCB3에 저장된 실행 시작 주소(스레드 코드3)로 점프하여 실행 시작 -&gt; U- TCB3이 스케줄 되었음</p>
</li>
</ul>
<table>
<thead>
<tr>
<th>항목</th>
<th>사용자 레벨 스레드</th>
<th>커널 레벨 스레드</th>
</tr>
</thead>
<tbody><tr>
<td>정의</td>
<td>스레드 라이브러리에 의해 스케줄되는 스레드</td>
<td>커널에 의해 스케줄되는 스레드</td>
</tr>
<tr>
<td>구현</td>
<td>스레드 라이브러리에 의해 구현되고 다루어짐</td>
<td>커널에 의해 구현. 커널 API(시스템 호출) 필요</td>
</tr>
<tr>
<td>스레드 스위칭</td>
<td>사용자 모드에서 스레드 라이브러리에 의해 실행</td>
<td>커널 모드에서 커널에 의해 실행</td>
</tr>
<tr>
<td>컨텍스트 스위칭 속도</td>
<td>커널 레벨 스레드보다 100배 이상 빠르다고 알려짐</td>
<td>커널 내에서 상당 시간 지연</td>
</tr>
<tr>
<td>멀티스레드 응용프로그램</td>
<td>스레드 라이브러리를 이용하여 작성하기 쉽고, 스레드 생성 속도 빠름</td>
<td>시스템 호출을 이용하여 스레드 생성. 스레드 생성 속도 느림</td>
</tr>
<tr>
<td>이식성</td>
<td>운영체제 상관없이 작성 가능하므로 높은 이식성 스레드를 지원하지 않는 운영체제에서도 가능</td>
<td>스레드를 생성하고 다루는 시스템 호출이 운영체제마다 다르므로 이식성이 낮음</td>
</tr>
<tr>
<td>병렬성</td>
<td>멀티 CPU 컴퓨터나 멀티 코어 CPU에서 멀티스레드의 병령처리 안 됨</td>
<td>높은 병렬성. 커널 레벨 스레드들이 서로 다른 CPU나 서로 다른 코어에서 병렬 실행 가능</td>
</tr>
<tr>
<td>병렬성의 종류</td>
<td>concurrency</td>
<td>parallelism</td>
</tr>
<tr>
<td>블록킹</td>
<td>하나의 사용자 레벨 스레드가 시스템 호출 도중 입출력 등으로 인해 중단되면 프로세스의 모든 사용자 레벨 스레드가 중단됨</td>
<td>하나의 커널 레벨 스레드가 시시템 호출 도중 입출력 등으로 인해 중단되어도 해당 스레드만 중단</td>
</tr>
<tr>
<td>커널 부담</td>
<td>없음</td>
<td>커널 코드의 실행 시간 증가. 시스템 전체에 부담</td>
</tr>
<tr>
<td>스레드 동기화</td>
<td>스레드 라이브러리에 의해 수행</td>
<td>시스템 호출을 통해 커널에 의해 수행</td>
</tr>
<tr>
<td>관리의 효율성</td>
<td>커널 부담 없음</td>
<td>커널 부담</td>
</tr>
<tr>
<td>최근 경향</td>
<td>멀티 코어 CPU에 적합하지 않아 줄고 있는 추세</td>
<td>멀티 코어 CPU에서 높은 병렬성을 얻을 수 있어 많이 사용하는 추세</td>
</tr>
</tbody></table>
<h1 id="멀티스레드-구현">멀티스레드 구현</h1>
<h2 id="멀티스레드-구현-1">멀티스레드 구현</h2>
<ul>
<li><p>응용프로그램에서 작성한 스레드가 시스템에서 실행되도록 구현하는 방법</p>
<ul>
<li>사용자가 만든 스레드가 시스템에서 스케줄 되고 실행되도록 구현하는 방법</li>
<li>스레드 라이브러리와 커널의 시스템 호출의 상호 협력 필요</li>
</ul>
</li>
<li><p>3가지 방법
1) N:1 매핑(N개의 사용자 레벨 스레드를 1개의 커널 레벨 스레드로 매핑)
2) 1:1 매핑 (1개의 사용자 레벨 스레드를 1개의 커널 레벨 스레드로 매핑)
3) N:M 매핑 (N개의 사용자 레벨 스레드를 M개의 커널 레벨 스레드로 매핑)</p>
<h2 id="n--1-매핑">N : 1 매핑</h2>
</li>
<li><p>운영체제가 모든 프로세스를 단일 스레드 프로세스로 다룸</p>
</li>
<li><p>프로세스 당 1개의 커널 레벨 스레드(TCB) 생성</p>
<ul>
<li>스케줄 가능한 엔터티라고 부름</li>
<li>프로세스의 모든 사용자 레벨 스레드가 1개의 커널 레벨 스레드에 매핑</li>
</ul>
</li>
<li><p>사용자 레벨 스레드는 스레드 라이브러리에 의해 스위치 된다.</p>
</li>
</ul>
<blockquote>
</blockquote>
<p>매핑의 뜻</p>
<ul>
<li>사용자 레벨 스레드는 해당 커널 레벨 스레드가 스케줄되어야 실행 가능하도록 묶여 있음</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/89c793e4-7354-4001-bb8b-e4953fa2d312/image.png" alt=""></p>
<ul>
<li>N:1 매핑의 장단점
1) 장점</li>
<li>단일 코어 CPU에서 멀티스레드 응용프로그램의 실행속도가 전반적으로 빠르다.<ul>
<li>스레드 생성, 스케줄, 동기화 등이 커널로의 진입없이 사용자 공간에서 이루어지므로</li>
</ul>
</li>
</ul>
<p>2) 단점</p>
<ul>
<li><p>멀티 코어 CPU가 보편화된 현대 컴퓨터에서 비효율적</p>
<ul>
<li>사용자 레벨 스레드의 병렬처리 안됨</li>
</ul>
</li>
<li><p>하나의 사용자 레벨 스레드가 블록되면 프로세스 전체 블록</p>
<ul>
<li>다른 사용자 레벨 스레드도 실행되지 못함<h2 id="1--1-매핑">1 : 1 매핑</h2>
</li>
</ul>
</li>
<li><p>사용자 레벨 스레드 당 1개의 커널 레벨 스레드(TCB) 생성</p>
</li>
<li><p>사용자 레벨 스레드는 매핑된 커널 레벨 스레드가 스케줄되면 실행</p>
</li>
<li><p>1:1 매핑의 장단점
1) 장점</p>
</li>
<li><p>개념이 단순하여 구현이 용이</p>
</li>
<li><p>멀티 코어 CPU에서 멀티스레드 응용프로그램에게 높은 병렬성제공</p>
</li>
<li><p>하나의 사용자 레벨 스레드가 블록되어도 응용프로그램 전체가 블록되지 않음</p>
</li>
</ul>
<p>2) 단점</p>
<ul>
<li>커널에게는 부담스러운 정책</li>
<li>사용자 레벨 스레드가 많아지면 모두 커널의 부담</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/4778d40f-fef7-4b95-bc51-15ca8e354961/image.png" alt=""></p>
<h2 id="n--m-매핑">N : M 매핑</h2>
<ul>
<li><p>N개의 사용자 레벨 스레드를 M개의 커널 레벨 스레드에 매핑</p>
</li>
<li><p>N:M 매핑의 장단점
1) 장점</p>
</li>
<li><p>1:1 매핑에 비해 커널 엔터티 개수가 작아 커널의 부담이 적음</p>
</li>
</ul>
<p>2) 단점</p>
<ul>
<li>구현하기 복잡하여 현대의 운영체제에서는 거의 사용되지 않음</li>
</ul>
<p>이 글이 문제가 된다면 삭제하겠습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] 3. 프로세스와 프로세스 관리]]></title>
            <link>https://velog.io/@passion_man/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-3.-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EA%B4%80%EB%A6%AC</link>
            <guid>https://velog.io/@passion_man/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-3.-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EA%B4%80%EB%A6%AC</guid>
            <pubDate>Mon, 30 May 2022 04:42:47 GMT</pubDate>
            <description><![CDATA[<h1 id="프로세스-개요">프로세스 개요</h1>
<h2 id="프로세스-개요-1">프로세스 개요</h2>
<p>** 프로그램 : 하드디스크 등의 저장 매체에 저장. 실행 파일의 형태</p>
<ul>
<li>프로세스 : 프로그램이 메모리에 적재되어 실행 중인 상태<ul>
<li>필요한 모든 자원 할당 받음</li>
<li>자원 : 코드공간, 데이터공간, 스택공간, 힙공간<h2 id="프로세스-특징">프로세스 특징</h2>
</li>
</ul>
</li>
<li>프로세스 특징</li>
</ul>
<ol>
<li>운영체제는 프로그램을 메모리에 적재하고 프로세스로 다룸</li>
<li>운영체제는 프로세스에게 실행에 필요한 메모리 할당, 이곳에 코드와 데이터 등 적재</li>
<li>프로세스들은 서로 독립적인 메모리 공간을 가짐. 다른 프로세스의 영역에 접근 불허</li>
<li>커널은 각 프로세스의 메모리 위치와 크기 정보를 관리한다.</li>
<li>커널은 프로세스마다 고유한 번호(프로세스 ID) 할당</li>
<li>프로세스에 관한 모든 정보는 커널이 관리</li>
<li>프로세스는 실행-대기-잠자기-대기-실행-종료 등의 생명주기를 가짐</li>
<li>프로세스를 만들고, 실행하고, 대기시키고, 종료시키는 모든 관리는 커널에 의해 수행
<img src="https://velog.velcdn.com/images/passion_man/post/3400ca03-cefb-41f0-a942-c48f4b2c2fc3/image.png" alt=""></li>
</ol>
<h2 id="프로세스-관리">프로세스 관리</h2>
<ul>
<li><p>프로세스의 생성에서 종료까지 관리는 모두 커널에 의해 이루어짐</p>
<ul>
<li>커널 영역에 프로세스 테이블을 만들고, 프로세스의 목록 관리</li>
</ul>
</li>
<li><p>관리내용</p>
<ul>
<li>프로세스 생성, 실행, 일시 중단 및 재개, 정보 관리, 프로세스 통신, 프로세스 동기화, 프로세스 중단, 프로세스 컨텍스트 스위칭</li>
</ul>
</li>
<li><p>프로그램의 다중 인스턴스</p>
<ul>
<li>한 프로그램을 여러 번 실행시켜 다중 인스턴스를 생성하면 어떻게 될까?</li>
<li>운영체제는 프로그램을 실행할 때마다 독립된 프로세스 생성</li>
</ul>
<ul>
<li>각 프로세스에게 독립된 메모리 공간 할당</li>
<li>운영체제는 다중 인스턴스 프로세스들을 별개의 프로세스들로 취급</li>
</ul>
</li>
</ul>
<h2 id="cpu-주소-공간">CPU 주소 공간</h2>
<p>** CPU가 주소선을 통해 엑세스할 수 있는 전체 메모리 공간</p>
<ul>
<li><p>공간 크기</p>
<ul>
<li>CPU의 주소선의 수에 의해 결정</li>
<li>32비트 CPU -&gt; 32개의 주소선 -&gt; 232개의 주소 -&gt; 4GB 공간</li>
</ul>
</li>
<li><p>주소공간은 0번지부터 시작</p>
<ul>
<li>1번지의 저장 공간 크기는 1바이트<h2 id="프로세스를-구성한-4개의-메모리-영역">프로세스를 구성한 4개의 메모리 영역</h2>
</li>
</ul>
</li>
</ul>
<ol>
<li>코드 영역</li>
</ol>
<ul>
<li>실행될 프로그램 코드가 적재되는 영역</li>
<li>사용자가 작성한 모든 함수의 코드</li>
<li>사용자가 호출한 라이브러리 함수들의 코드</li>
</ul>
<ol start="2">
<li>데이터 영역 (상수 공간)</li>
</ol>
<ul>
<li>전역 변수 공간, 정적 데이터 공간 ( 사용자 프로그램과 라이브러리 포함 )</li>
<li>프로그램에서 고정적으로 만든 변수 공간 (상수 공간)</li>
<li>프로세스 적재 시 할당, 종료 시 소멸</li>
</ul>
<ol start="3">
<li>힙 영역</li>
</ol>
<ul>
<li>프로세스가 실행 도중 동적으로 사용할 수 있도록 할당된 공간</li>
<li>malloc() 등으로 할당받는 공간은 힙 영역에서 할당</li>
<li>힙 영역에서 아래 번지로 내려가면서 할당</li>
</ul>
<ol start="4">
<li>스택 영역</li>
</ol>
<ul>
<li>함수가 실행될 때 사용될 데이터를 위해 할당된 공간</li>
<li>매개변수들, 지역변수들, 함수 종료 후 돌아갈 주소 등</li>
<li>함수는 호출될 때, 스택 영역에서 위쪽으로 공간 할당</li>
<li>함수가 return 하면 할당된 공간 반환</li>
</ul>
<p>** 함수 호출 외에 프로세스에서 필요시 사용가능</p>
<h2 id="프로세스-주소-공간">프로세스 주소 공간</h2>
<blockquote>
</blockquote>
<ul>
<li><p>프로세스가 실행 중에 접근할 수 있도록 허용된 주소의 최대 범위</p>
</li>
<li><p>프로세스 주소 공간은 논리 공간(가상 공간) - 0번지에서 시작하여 연속적인 주소</p>
</li>
<li><p>프로세스 주소 공간 크기</p>
<ul>
<li>CPU 가 엑세스할 수 있는 전체 크기 ( 32비트 CPU의 경우, 4GB )</li>
<li>프로세스 주소 공간 크기는 프로세스의 현재 크기와 다름</li>
<li>프로세스 주소 공간의 크기 : 프로세스가 액세스할 수 있는 최대 크    기</li>
<li>프로세스 현재 크기 : 적재된 코드 + 전역변수 + 힙 영역에서 할당받아 사용 중인 동적 메모리 공간 + 현재 스택 영역에 저장된 데이터 크기</li>
</ul>
</li>
</ul>
<p>** 프로세스 주소 공간은 2부분으로 나뉘어짐</p>
<p>1) 사용자 공간</p>
<ul>
<li>프로세스의 코드, 데이터, 힙, 스택 영역이 할당되는 공간</li>
<li>코드와 데이터 영역의 크기는 프로세스 시작 시 결정</li>
<li>힙과 스택 영역의 크기는 정해져 있지 않음</li>
<li>힙 영역은 아래로 자라고, 스택은 위로 자람</li>
</ul>
<p>2) 커널 공간</p>
<ul>
<li>프로세스가 시스템 호출을 통해 이용하는 커널 공간</li>
<li>커널 코드, 커널 데이터, 커널 스택(커널 코드가 실행될 때)</li>
<li>커널 공간은 모든 사용자 프로세스에 의해 공유 ( 프로세스나 스레드가 스택이나 힙을 소유 )</li>
</ul>
<h2 id="프로세스-주소-공간의-특징">프로세스 주소 공간의 특징</h2>
<p>** 프로세스의 주소 공간은 가상 공간 </p>
<ul>
<li><p>프로세스의 주소 공간은 사용자나 개발자가 보는 관점</p>
<ul>
<li>자신이 작성한 프로그램이 0번지부터 시작하여,</li>
<li>연속적인 메모리 공간에 형성되고,</li>
<li>CPU가 액세스할 수 있는 최대 크기의 메모리가 설치되어 있다고 상상</li>
</ul>
</li>
<li><p>실제 상황</p>
<ul>
<li>설치된 물리 메모리의 크기는 주소 공간보다 작을 수 있고,</li>
<li>프로세스의 코드, 데이터, 힙, 스택은 물리 메모리에 흩어져 저장됨 (연속적인 메모리 공간이 아님)</li>
</ul>
</li>
</ul>
<ol>
<li>프로세스 주소 공간은 프로세스별로 주어지는가? YES</li>
</ol>
<ul>
<li>프로세스마다 주소 공간은 별개이다.</li>
</ul>
<ol start="2">
<li>그러면, 프로세스 주소 공간은 충돌하는가? NO</li>
</ol>
<ul>
<li>프로세스 주소 공간은 가상 주소 공간이다.</li>
<li>가상 주소가 실제 주소로 매핑되므로, 물리 메모리에서는 충돌하지 않는다.</li>
</ul>
<blockquote>
</blockquote>
<p>[가상 주소 공간의 물리 메모리로의 매핑]</p>
<blockquote>
</blockquote>
<ul>
<li>사용자는 연속적인 공간(가상 주소 공간)으로 생각 -&gt; 그러나 가상 주소의 데이터가 실제 메모리에 분산되어 있어 어느 번지에 있을지 알 수 없음</li>
</ul>
<blockquote>
</blockquote>
<ul>
<li>가상메모리 운영 방식 : LRU (least, recently, uses- 최근 최소 사용) 필요한 것만 RAM으로 가져오고 오래동안 사용하지 않는 건 하드디스크에 내려놓는다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/2d3723f5-2631-4a90-8176-19d5ee59bf6f/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/3fcfd994-8926-4e35-a44c-fefbb1d0c4d8/image.png" alt=""></p>
<h2 id="커널-공간의-의미">커널 공간의 의미</h2>
<p>** 각 프로세스는 독립된 사용자 공간 소유, 커널 공간 공유</p>
<ul>
<li><p>커널 공간</p>
<ul>
<li>프로세스가 사용자 코드에서 시스템 호출을 통해 커널 코드 실행할 때 커널 공간 사용<ul>
<li>사용자 프로세스가 커널 모드에서 실행되고 있다고 함</li>
<li>커널 코드를 실행하고 있는 것은 사용자 프로세스임</li>
<li>커널 코드가 적재된 물리 메모리의 위치 역시 사용자 프로세스가 소유한 매핑 테이블 사용</li>
</ul>
</li>
</ul>
</li>
<li><p>사용자 공간과 커널 공간의 결론</p>
<ul>
<li>프로세스마다 각각 사용자 주소 공간이 있다.</li>
<li>시스템 전체에는 하나의 커널 주소 공간이 있다.</li>
<li>모든 프로세스는 커널 주소 공간을 공유한다.<h1 id="커널의-프로세스-관리">커널의 프로세스 관리</h1>
<h2 id="프로세스-테이블과-프로세스-제어-블록">프로세스 테이블과 프로세스 제어 블록</h2>
프로세스 테이블과 프로세스 제어 블록</li>
</ul>
</li>
</ul>
<p>1) 프로세스 테이블</p>
<ul>
<li>시스템의 모든 프로세스들을 관리하기 위한 표</li>
<li>시스템에 한 개만 있음</li>
<li>구현 방식은 운영체제마다 다름</li>
</ul>
<p>2) 프로세스 제어 블록(PCB : Process Control Block)</p>
<ul>
<li>프로세스에 관한 정보를 저장하는 구조체</li>
<li>프로세스 당 하나씩 존재</li>
<li>프로세스가 생성될 때 만들어지고 종료되면 삭제</li>
<li>커널에 의해 생성, 저장, 읽혀지는 등 관리</li>
</ul>
<blockquote>
</blockquote>
<ul>
<li><p>nice 값 : Linux 상에서 Process 가 실행될 때, nice 라는 값을 가지고 실행되는데, nice 값은 process 간의 우선순위를 말함</p>
</li>
<li><p>프로세스 제어 블록에 저장되는 정보 (운영체제마다 프로세스 제어 블록에 저장되는 요소와 프로세스 상태 등이 다름)</p>
</li>
</ul>
<ol>
<li>프로세스 번호(PID, Process ID) : 정수, 유일한 번호, 이 번호로 프로세스 구분</li>
<li>부모 프로세스 번호(PPID, Parent Process ID) : 부모 프로세스의 PID</li>
<li>프로세스 상태(Process State) 정보</li>
<li>CPU 컨텍스트 정보</li>
</ol>
<ul>
<li>PC(Program Counter) : 선택되면 실행을 시작할 프로세스 내 코드 주소<ul>
<li>사용자 모드에 있었던 경우, 사용자 공간의 코드 주소</li>
<li>커널 모드에 있었던 경우, 커널 공간의 코드 주소</li>
<li>SP(Stack Pointer)</li>
<li>기타 레지스터</li>
</ul>
</li>
</ul>
<ol start="5">
<li>스케줄링 정보</li>
</ol>
<ul>
<li>우선 순위 값, nice 값, 스케줄 큐에 대한 포인터 등</li>
</ul>
<ol start="6">
<li>프로세스 종료 코드(정수 0 ~ 255)</li>
</ol>
<ul>
<li>exit() 시스템 호출의 매개변수 값, return 문의 리턴 값. 부모 프로세스에게 전달</li>
</ul>
<ol start="7">
<li>열어놓은 파일 디스크립터들이 저장되는 배열</li>
<li>메모리 관리 정보</li>
</ol>
<ul>
<li>페이지 테이블의 메모리 위치, 프로세스에게 할당된 물리 메모리의 주소 등</li>
</ul>
<ol start="9">
<li>프로세스 사이의 통신 정보들</li>
<li>회계 정보</li>
</ol>
<ul>
<li>CPU의 사용 시간, 시간 제한, 프로세스의 총 경과시간 등</li>
</ul>
<ol start="11">
<li>프로세스 소유자 이름</li>
</ol>
<ul>
<li>프로세스를 생성한 사용자의 로그인 이름 정보
<img src="https://velog.velcdn.com/images/passion_man/post/93254046-9f3b-4df8-8192-6b638bf850be/image.png" alt=""></li>
</ul>
<h2 id="프로세스의-생명주기">프로세스의 생명주기</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/2f19fc73-c6d6-4829-a257-7002974a063a/image.png" alt=""></p>
<ol>
<li>New(생성 상태)</li>
</ol>
<ul>
<li>프로세스가 생성된 상태. 메모리 할당 및 필요한 자원 적재</li>
</ul>
<ol start="2">
<li>Ready(준비 상태)</li>
</ol>
<ul>
<li>프로세스가 스케줄링을 기다리는 준비 상태</li>
<li>프로세스는 준비 큐에서 대기</li>
<li>스케줄링 되면 Running 상태로 되고 CPU에 의해 실행됨</li>
</ul>
<ol start="3">
<li>Running(실행 상태)</li>
</ol>
<ul>
<li>프로세스가 CPU에 의해 현재 실행되고 있는 상태</li>
<li>CPU의 시간할당량(타임슬라이스)가 지나면 다시 Ready 상태로 바뀌고 준비 큐에 삽입</li>
<li>프로세스가 입출력을 시행하면 커널은 프로세스를 Blocked 상태로 만들고 대기 큐에 삽입</li>
</ul>
<ol start="4">
<li>Blocked/Wait(블록 상태)</li>
</ol>
<ul>
<li>프로세스가 자원을 요청하거나, 입출력을 요청하고 완료를 기다리는 상태</li>
<li>입출력이 완료되면 프로세스는 Ready 상태로 바뀌고 준비 큐에 삽입</li>
</ul>
<ol start="5">
<li>Terminated/Zombie 상태</li>
</ol>
<ul>
<li>프로세스가 종료된 상태 (프로세스가 차지하고 있던 메모리와 할당받았던 자원들을 모두 반환, 열어 놓은 파일 닫힘)</li>
<li>프로세스가 PCB에 남긴 종료코드를 부모 프로세스가 읽어가지 않아 완전히 종료되지 않은 상태 - 좀비 상태라고 부름</li>
<li>아직 PCB가 남아있음</li>
</ul>
<ol start="6">
<li>Terminated/Out 상태</li>
</ol>
<ul>
<li><p>프로세스가 종료하면서 남긴 종료코드를 부모 프로세스가 읽어 가서 완전히 종료된 상태</p>
</li>
<li><p>프로세스 테이블의 항목과 PCB가 시스템에서 완전히 제거된 상태</p>
<h2 id="프로세스-스케줄링과-컨텍스트-스위칭">프로세스 스케줄링과 컨텍스트 스위칭</h2>
</li>
<li><p>프로세스 스케줄링</p>
<ul>
<li>과거 운영체제에서 실행단위는 프로세스였음</li>
<li>Ready 상태의 프로세스 중에 실행 시킬 프로세스 선택</li>
</ul>
</li>
<li><p>오늘날 운영체제는 스레드를 대상으로 스케줄링</p>
<ul>
<li>오늘날 프로세스 스케줄링은 없음</li>
<li>오늘날 운영체제에서 실행 단위는 스레드</li>
<li>Ready 상태의 스레드 중 실행시킬 스레드 선택</li>
</ul>
</li>
<li><p>프로세스는?</p>
<ul>
<li>프로세스는 스레드들에게 공유 자원을 제공하는 컨테이너로 역할이 바뀌었음<h1 id="프로세스-계층-구조">프로세스 계층 구조</h1>
<h2 id="프로세스-부모-자식-관계">프로세스 부모-자식 관계</h2>
</li>
</ul>
</li>
<li><ul>
<li>프로세스는 일반적으로 부모-자식 관계 (윈도우에서 프로세스는 모두 동등 - 계층 관계 아님)</li>
</ul>
</li>
<li><p>#0 프로세스가 시스템 부팅시 실행되는 최초의 프로세스, 조상 프로세스</p>
</li>
<li><p>부모 프로세스는 여러 개의 자식 프로세스를 가질 수 있음</p>
</li>
<li><p>모든 프로세스는 부모 프로세스를 가짐 (#0 프로세스 제외)</p>
</li>
<li><p>자식 프로세스 생성</p>
<ul>
<li>모든 프로세스는 프로세스(부모)에 의해 생성<ul>
<li>프로세스 생성은 시스템 호출을 통해서만 가능</li>
</ul>
</li>
</ul>
</li>
</ul>
<blockquote>
</blockquote>
<p>fork(), clone() 등의 커널 코드가 자식 프로세스 생성
예외 : PID 0,1,2 등의 몇몇 조상 프로세스는 시스템 호출이 아닌 수작업으로 생성</p>
<blockquote>
</blockquote>
<p>리눅스 사례
#0 프로세스 - swapper/idle 프로세스 (hand-crafted)
#1 프로세스 - init 프로세스(hand-crafted)
    - 부팅 후 생성되는 모든 사용자 프로세스의 조상
#2 프로세스 - kthreadd 프로세스
    - 커널 모드에서 커널 코드로만 실행되는 모든 커널 프로세스의 조상</p>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/passion_man/post/51cd20a6-b8b7-4069-bdd5-2dfe490a339f/image.png" alt=""></p>
<h2 id="0과-1-프로세스--idle-프로세스와-init-프로세스">#0과 #1 프로세스 : idle 프로세스와 init 프로세스</h2>
<ul>
<li><p>#0 프로세스</p>
<ul>
<li>최고의 어른(조상) 프로세스</li>
<li>Unix의 #0 프로세스<ul>
<li>swapper 라고 불림, 부팅을 담당하고 #1 프로세스 생성</li>
</ul>
</li>
</ul>
</li>
<li><p>Linux의 #0 프로세스</p>
<ul>
<li>idle 프로세스, 부팅 관여 없이 아무 일도 하지 않고 루프<ul>
<li>우선 순위가 가장 낮은 프로세스, 다른 프로세스가 있으면 실행될 일 없음</li>
<li>실행 중인 프로세스가 1개도 없는 상태에 빠지지 않게 하기 위해 만든 프로세스</li>
<li>Unix 시절의 관례에 따르기 위해 만들어진 프로세스</li>
</ul>
</li>
</ul>
</li>
<li><p>Windows의 #0 프로세스 : system idle process(시스템 유휴 프로세스)</p>
<ul>
<li>아무 일도 하지 않고 루프를 도는 단순 프로세스</li>
</ul>
</li>
<li><p>프로세스를 다루는 시스템 호출</p>
</li>
</ul>
<ol>
<li>fork() - 자식 프로세스를 생성하는 시스템 호출</li>
<li>exit() - 프로세스의 종료를 커널에 알리는 시스템 호출</li>
<li>wait() - 부모가 자식 프로세스의 종료를 기다리고 확인하는 시스템 호출</li>
</ol>
<h2 id="프로세스-종료">프로세스 종료</h2>
<p>** 좀비 프로세스 : 종료 후 방치된 자식 프로세스</p>
<ul>
<li><p>프로세스가 종료할 때</p>
<ul>
<li>PCB에, 종료 코드 저장</li>
<li>PCB에 프로세스 상태를 Terminated 라고 표시</li>
<li>프로세스에게 할당된 모든 메모리 반환<ul>
<li>PCB와 프로세스 테이블의 항목은 제거되지 않음</li>
</ul>
</li>
</ul>
</li>
<li><p>부모 프로세스의 의무</p>
<ul>
<li>wait() 시스템 호출을 통해 프로세스의 종료 코드를 읽어야 함</li>
</ul>
</li>
<li><p>좀비 프로세스</p>
<ul>
<li>종료하였지만, 부모가 종료 코드를 읽지 않은 상태의 프로세스</li>
<li>프로세스 리스트를 출력할 때(ps명령으로) 나타남</li>
</ul>
</li>
<li><p>좀비 프로세스 제거</p>
<ul>
<li>부모에게 SIGCHLD 핸들러가 없다면 좀비는 제거되지 못함</li>
<li>부모 프로세스를 강제 종료시키면,</li>
<li>좀비는 init 프로세스의 자식이 되고</li>
<li>init이 wait() 호출하여 좀비 프로세스 제거</li>
<li>쉘에서 부모 프로세스에게 SIGCHLD 신호보내기<ul>
<li>부모 프로세스에서 wait() 함수를 호출하여 처리</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="고아-프로세스와-입양">고아 프로세스와 입양</h2>
<p>고아 프로세스 : 부모가 먼저 종료한 자식 프로세스</p>
<ul>
<li>부모 프로세스가 종료할 때<ul>
<li>일반적으로<ul>
<li>커널(exit() 시스템 호출 코드)은 자식 프로세스가 있는지 확인</li>
<li>커널은 자식 프로세스(고아)를 init 프로세스에게 입양</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>운영체제에 따라, 혹은 쉘의 경우</p>
<ul>
<li>모든 자식 프로세스를 강제 종료시키기도 함<h2 id="여러종류의-프로세스">여러종류의 프로세스</h2>
</li>
</ul>
<p>1) 백그라운드 프로세스</p>
<ul>
<li>터미널에서 실행되었지만, 터미널 사용자와 대화가 없는 채 실행되는 프로세스</li>
<li>사용자와 대화없이 실행되는 프로세스</li>
<li>사용자 입력을 필요로 하지 않는 프로세스</li>
<li>idle 상태로 잠을 자거나 디스크에 스왑된 상태의 프로세스</li>
</ul>
<p>2) 포그라운드 프로세스</p>
<ul>
<li>실행되는 동안 터미널 사용자의 입력을 독점하는 프로세스</li>
</ul>
<p>3) CPU 집중 프로세스 vs. I/O 집중 프로세스</p>
<ul>
<li><p>CPU 집중프로세스</p>
<ul>
<li>대부분의 시간을 계산 중심의 일(CPU 작업)을 하느라 보내는 프로    세스</li>
<li>배열 곱, 인공지능 연산, 이미지 처리</li>
<li>CPU 속도가 성능 좌우</li>
</ul>
</li>
<li><p>I/O 집중 프로세스</p>
<ul>
<li>입출력 작업을 하느라 대부분의 시간을 보내는 프로세스</li>
<li>네트워크 전송, 파일 입출력에 집중된 프로세스</li>
<li>파일 서버, 웹 서버</li>
<li>입출력 장치나 입출력 시스템의 속도가 성능 좌우</li>
</ul>
</li>
<li><p>운영체제의 스케줄링 우선순위 : I/O 집중 프로세스 &gt; CPU 집중 프로세스</p>
<ul>
<li>I/O 작업을 하는 동안 다른 프로세스에게 CPU 할당 가능<h1 id="프로세스-제어">프로세스 제어</h1>
<h2 id="프로세스-생성">프로세스 생성</h2>
</li>
</ul>
</li>
<li><p>컴퓨터 시스템에서 프로세스가 생성되는 5가지 경우</p>
<ul>
<li>시스템 부팅과정에서 필요한 프로세스 생성</li>
<li>사용자의 로그인 후 사용자와 대화를 위한 프로세스 생성(bash 등     쉘)</li>
<li>새로운 프로세스를 생성하도록 하는 사용자의 명령(vi a.c, vi hello.c)</li>
<li>배치 작업 실행 시(at, batch 명령, &quot;몇 시에 ~해라&quot;)</li>
<li>사용자 응용프로그램이 시스템 호출로 새 프로세스 생성</li>
</ul>
</li>
<li><p>프로세스 생성</p>
<ul>
<li>프로세스가 프로세스를 생성</li>
</ul>
</li>
<li><p>시스템 호출을 통해서만 프로세스 생성</p>
<ul>
<li>커널만이 프로세스 생성가능</li>
<li>리눅스 : fork() 시스템 호출</li>
<li>windows : CreateProcess() 등 시스템 호출</li>
</ul>
</li>
<li><p>프로세스 생성 과정
1) 새로운 PID 번호 할당
2) PCB 구조체 생성
3) 프로세스 테이블에서 새 항목 할당
4) 새로운 프로세스를 위한 메모리 공간 할당</p>
</li>
<li><blockquote>
<p>프로세스의 코드, 데이터, 스택, 힙 영역</p>
</blockquote>
</li>
<li><blockquote>
<p>할당받은 메모리 공간에 프로세스의 코드와 데이터 적재
5) PCB에 프로세스 정보 기록
6) PCB에 프로세스 상태를 ready 상태로 표시하고, 준비 큐에 넣어서 차후 스케줄되게 함</p>
</blockquote>
</li>
</ul>
<blockquote>
</blockquote>
<ul>
<li>fork() 시스템 호출로 자식 프로세스 생성<blockquote>
</blockquote>
int pid = fork();</li>
<li><blockquote>
<p>자식 프로세스 생성</p>
</blockquote>
</li>
<li><blockquote>
<p>부모 프로세스의 모든 환경, 메모리, PCB 등을 복사</p>
</blockquote>
</li>
<li><blockquote>
<p>부모와 동일한 모양이지만, 독립된 주소 공간 소유</p>
</blockquote>
리턴값</li>
<li><blockquote>
<p>부모 프로세스에게는 자식 프로세스의 PID 리턴</p>
</blockquote>
</li>
<li><blockquote>
<p>자식 프로세스에게는 0 리턴
<img src="https://velog.velcdn.com/images/passion_man/post/f6089095-87a0-442a-9b9c-7fea7d725ae4/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/474c52cc-e1f0-4b7d-8f51-95394f3c76d2/image.png" alt=""></p>
</blockquote>
</li>
</ul>
<blockquote>
</blockquote>
<p>프로세스 오버레이, exec()</p>
<blockquote>
</blockquote>
<p>프로세스 오버레이(process overlay)</p>
<blockquote>
</blockquote>
<p>현재 실행중인 프로세스의 주소 공간에 새로운 응용프로그램을 적재하여 실행시키는 기법</p>
<blockquote>
</blockquote>
<p>exec 패밀리 시스템 호출
-&gt; execlp(), execv(), execvp() 시스텔 호출들
-&gt; 실행 파일을 로딩하여 현재 프로세스의 이미지 위에 단순히 덮어쓰고 새로운 프로세스의 생성 과정을 거치지 않는다.</p>
<blockquote>
</blockquote>
<p>프로세스의 PID 변경 없음</p>
<blockquote>
</blockquote>
<p>프로세스의 코드, 데이터, 힙, 스택에 새로운 응용프로그램이 적재됨</p>
<blockquote>
</blockquote>
<p>보통 fork() 를 통해 생성된 자식 프로세스가 exec() 실행
<img src="https://velog.velcdn.com/images/passion_man/post/f3a5b0a0-7ffc-4067-b38d-6313d23cd5f1/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/5e872dd4-94de-4593-8eb0-c835d85e8e11/image.png" alt=""></p>
<h2 id="프로세스-종료와-종료-대기">프로세스 종료와 종료 대기</h2>
<ul>
<li><p>프로세스 종료</p>
<ul>
<li>exit() 시스템 호출</li>
<li>C프로그램의 main() 에서 리턴<ul>
<li>exit() 시스템 호출이 결국 실행되도록 컴파일 됨</li>
</ul>
</li>
</ul>
</li>
<li><p>종료 코드</p>
<ul>
<li>부모 프로세스에게 전달하는 값<ul>
<li>main() 함수의 리턴 값; return 종료 코드;</li>
<li>exit(종료코드)</li>
</ul>
</li>
</ul>
</li>
<li><p>exit() 시스템 호출로 프로세스 종료 과정</p>
</li>
</ul>
<p>1) 프로세스의 모든 자원 반환
    - 코드, 데이터, 스택, 힙 등의 모든 메모리 자원을 반환
    - 열어 놓은 파일이나 소켓 등을 닫음</p>
<p>2) PCB에 프로세스 상태를 Terminated 로 변경, PCB 에 종료 코드 저장
3) 자식 프로세스들을 init 프로세스에게 입양
4) 부모 프로세스에게 SIGCHLD 신호 전송
    - 부모가 SIGCHLD 신호 처리기를 작성하여 wait() 시스템 호출로 자식의 종료 코드 읽기 실행
    - 혹은 언젠가 부모가 자식의 죽음 처리. 그동안 자식은 좀비 상태에 있음</p>
<h2 id="종료코드의-의미와-범위">종료코드의 의미와 범위</h2>
<p>1) 종료 코드</p>
<ul>
<li>프로세스가 종료한 상태나 이유를 부모에게 전달하기 위한 것</li>
<li>POSIX 표준에서 0 ~ 255 사이의 1바이트 숫자<ul>
<li>정상종료는 0</li>
<li>1~255 : 개발자가 종료 이유를 임의로 정해 사용</li>
</ul>
</li>
</ul>
<p>2) 종료 코드 사용 시 유의할 점</p>
<ul>
<li>main 이나 exit()에서 255 이상의 값을 사용할 때 유의</li>
</ul>
<blockquote>
</blockquote>
<p>int main(){
return 300; // return 44; 와 같음
}
void func(){
exit(300); // exit(44) 와 같음
}</p>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/passion_man/post/a83ad753-7703-4ca7-8fce-f16e5d1f2f90/image.png" alt=""></p>
<ul>
<li>-1을 리턴하는 경우 (return -1, 혹은 exit(-1))</li>
<li><blockquote>
<p>-1 -&gt; 0xff -&gt; 양의 정수로 255. 그러므로 종료 코드로 255가 전달</p>
</blockquote>
<h2 id="프로세스-종료와-좀비-프로세스">프로세스 종료와 좀비 프로세스</h2>
1) 프로세스 종료</li>
<li>두 종류<ul>
<li>C언어에서 main() 함수의 종료나 exit() 을 호출한 정상 종료</li>
<li>다른 프로세스에 의해 강제 종료</li>
</ul>
</li>
</ul>
<p>2) 프로세스가 종료되면</p>
<ul>
<li>차지하고 있던 메모리와 자원 모두 반환</li>
<li>PCB는 프로세스 테이블에서 제거되지 않음</li>
<li>프로세스 상태 : Terminated</li>
</ul>
<p>** 죽은 프로세스가 wait(), 혹은 CloseHandle() 시스템 호출을 통해, 죽은 자식이 남긴 정보를 읽게 되면 자식 프로세스의 PCB 가 완전히 제거</p>
<blockquote>
</blockquote>
<p>좀비 프로세스
종료할 때 리턴한 정보(main() 함수에서 리턴값)를 부모 프로세스가 읽지 않을 때, 죽었지만 PCB만 남아 완전히 제거되지 못한 상태</p>
<p>이 글이 문제가 된다면 삭제하겠습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] 2. 컴퓨터 시스템과 운영체제]]></title>
            <link>https://velog.io/@passion_man/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-2.-%EC%BB%B4%ED%93%A8%ED%84%B0-%EC%8B%9C%EC%8A%A4%ED%85%9C%EA%B3%BC-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C</link>
            <guid>https://velog.io/@passion_man/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-2.-%EC%BB%B4%ED%93%A8%ED%84%B0-%EC%8B%9C%EC%8A%A4%ED%85%9C%EA%B3%BC-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C</guid>
            <pubDate>Mon, 30 May 2022 04:42:25 GMT</pubDate>
            <description><![CDATA[<h1 id="컴퓨터-시스템과-하드웨어">컴퓨터 시스템과 하드웨어</h1>
<h2 id="컴퓨터-시스템의-범위">컴퓨터 시스템의 범위</h2>
<ul>
<li><p>컴퓨터 시스템의 계층</p>
<ul>
<li>응용프로그램 층</li>
<li>운영체제 층</li>
<li>컴퓨터 하드웨어 층</li>
</ul>
</li>
<li><p>컴퓨터 시스템 계층 구조의 특징</p>
<ul>
<li>사용자는 응용프로그램/도구프로그램을 통해 컴퓨터 활용</li>
<li>하드웨어는 모두 운영체제의 배타적 독점적 지배를 받음</li>
<li>사용자나 응용프로그램의 하드웨어에 대한 직접 접근 불허 (반드시 운영체제를 통해서만 접근 가능)</li>
</ul>
</li>
<li><p>계층 구조에서 보는 운영체제의 기능</p>
<ul>
<li>사용자가 하드웨어에 대해 몰라도 컴퓨터를 사용할 수 있도록 함</li>
<li>응용프로그램과 하드웨어 사이의 중계<h2 id="컴퓨터-하드웨어-구성">컴퓨터 하드웨어 구성</h2>
<img src="https://velog.velcdn.com/images/passion_man/post/18699d63-34d2-449d-8e9f-f158ebf065f7/image.png" alt=""><h2 id="컴퓨터-하드웨어-설명">컴퓨터 하드웨어 설명</h2>
</li>
</ul>
</li>
<li><p>CPU (Central Processing Unit)</p>
<ul>
<li>프로그램 코드, 기계 명령을 해석하여 실행하는 중앙처리장치</li>
<li>컴퓨터의 가장 핵심 장치</li>
<li>전원이 공급될 때 작동 시작, 메모리에 적재된 프로그램 실행</li>
</ul>
</li>
<li><p>메모리</p>
<ul>
<li>반도체 메모리 RAM</li>
<li>CPU에 의해 실행되는 프로그램 코드와 데이터가 적재되는 공간</li>
<li>프로그램은 실행되기 위해서 반드시 메모리에 적재되어야 함</li>
</ul>
</li>
<li><p>캐시 메모리(Cache Memory)</p>
<ul>
<li>CPU 처리속도가 메모리 속도에 비해 빠르게 향상 -&gt; CPU는 느린 메모리 때문에 대기시간이 늘게 되었음</li>
<li>CPU의 프로그램 실행 속도를 높이기 위해, CPU와 메모리 사이에 설치되는 소량의 빠른 메모리, 고가의 메모리
※ 온칩 캐시 - CPU 내부에 설치되는 캐시
※ 옵치 캐시 - CPU 외부에 설치되는 캐시</li>
<li>캐시 메모리가 있는 경우 CPU는 캐시 메모리에서만 프로그램 실행 (실행하고자하는 프로그램과 데이터는 먼저 메모리에서 캐시로 옮겨져야 함)</li>
</ul>
</li>
<li><p>장치들</p>
<ul>
<li>키보드, 프린터, 스캐너 등</li>
</ul>
</li>
<li><p>버스</p>
<ul>
<li><p>하드웨어들이 데이터를 주고받기 위해 0과 1의 디지털 신호가 지나가는 여러 가닥의 선을 다발로 묶어 부르는 용어</p>
</li>
<li><p>버스의 종류 : 주소 버스, 데이터 버스, 제어 버스</p>
</li>
<li><p>주소</p>
<ul>
<li><p>메모리나 입출력 장치나 저장 장치 내에 있는 저장소에 대한 번지</p>
</li>
<li><p>가장 작은 번지는 0번지이고 그 외는 양의 정수</p>
</li>
<li><p>주소 버스는 주소 값이 전달되는 여러 선의 다발을 부름 (16bit면 16가닥)</p>
</li>
</ul>
</li>
<li><p>CPU는 메모리나 입출력 장치에 값을 쓰거나 읽을 때 반드시 주소를 발생시킴</p>
</li>
</ul>
</li>
</ul>
<blockquote>
</blockquote>
<p>버스는 목적에 따라 구분</p>
<blockquote>
</blockquote>
<table>
<thead>
<tr>
<th>시스템 버스</th>
<th>입출력 버스</th>
</tr>
</thead>
<tbody><tr>
<td>CPU, 캐시, 메모리 등 빠른 하드웨어들 사이에 신호 전송</td>
<td>상대적으로 느린 입출력 장치들로부터 입출력 데이터 전송</td>
</tr>
<tr>
<td>비유 : 고속도로</td>
<td>비유 : 일반도로</td>
</tr>
</tbody></table>
<ul>
<li>입출력 제어 장치 및 시스템 제어 회로<ul>
<li>입출력 장치에게 명령을 하달</li>
<li>메모리와 입출력 장치 사이에 혹은 CPU와 입출력 장치 사이에 데이터가 전달 중계</li>
<li>DMAC(Direct Memory Access Controller), 인터럽트 제어장치(Interrupt Controller, INTC) 등 포함</li>
</ul>
</li>
</ul>
<h2 id="cpu와-메모리의-관계">CPU와 메모리의 관계</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/06db2ed7-1a48-47fa-b6a6-44702af55996/image.png" alt=""></p>
<ul>
<li><p>CPU</p>
<ul>
<li><p>능동적 소자, 메모리 액세스 시 주소 발생</p>
</li>
<li><p>32비트 CPU, 32비트 운영체제, 32비트 컴퓨터</p>
</li>
<li><p>CPU에 32개 주소선</p>
</li>
<li><p>CPU가 액세스하는 주소 범위 : 0~ 2³² -1 번지</p>
</li>
<li><p>CPU가 최대 액세스할 수 있는 메모리의 크기 : 4GB</p>
</li>
<li><p>한 번지의 저장공간이 1바이트이므로, 2³² 바이트 = 4GB</p>
</li>
<li><p>32비트 CPU를 가진 컴퓨터에 4GB이상 메모리를 달아도 소용없음</p>
</li>
<li><p>CPU에 입출력되는 32개의 데이터 선 ( 한 번에 32비트 읽고 쓰기 가능 )</p>
</li>
<li><p>32비트 CPU는 32개 데이터선을 통해 32비트를 한 번에 메모리에서 읽고 쓰고 한 번에 32비트 더하기를 한다.</p>
</li>
</ul>
</li>
</ul>
<blockquote>
<p>[참고]
-&gt; 2<sup>10</sup> = 1KB
-&gt; 2<sup>20</sup> = 2<sup>10</sup> x 2<sup>10</sup> = 1MB
-&gt; 2<sup>30</sup> = 2<sup>20</sup>x 2<sup>10</sup> = 1GB 
-&gt; 2<sup>32</sup> = 2<sup>2</sup> x 2<sup>30</sup> = 4 x 1GB = 4GB</p>
</blockquote>
<ul>
<li>CPU와 메모리는 시스템 버스를 통해서 소통을 하면서 데이터를 주고 받는다.</li>
<li>메모리의 역할은 CPU에게 데이터를 전달하거나 CPU에서 처리된 데이터를 저장하는 역할을 한다.</li>
<li>CPU와 메모리가 연결된 버스는 크게 3가지가 있다.<ul>
<li>컨트롤 버스 : CPU가 메모리에게 데이터를 요청하거나 저장하라고 하는 정보를 주고받는 버스</li>
<li>주소 버스 : 메모리에서 해당 데이터의 주소 정보를 주고 받는 버스</li>
<li>데이터 버스 : 실제 주소에 저장되어 있는 데이터를 주고 받는 버스</li>
</ul>
</li>
</ul>
<h2 id="명령">명령</h2>
<p>1) 명령 처리 과정</p>
<ul>
<li><p>CPU 레지스터들</p>
<ul>
<li>PC(Program Counter) - 다음에 실행할 명령의 메모리 주소 저장</li>
<li>IR(Instruction Register) - 현재 실행하기 위해 메모리로부터 읽어 온 명령 저장</li>
<li>SP(Stack Pointer) - 스택의 톱 메모리 주소 저장</li>
<li>데이터 레지스터들(data registers) - 연산에 사용될 데이터들을     저장</li>
<li>상태 레지스터(status register) - CPU의 상태 정보나 인터럽트 금지 등의 제어 정보 저장</li>
<li>기타 여러 레지스터 - 페이지 테이블이 저장된 메모리 주소를 가리키는 레지스터 등</li>
</ul>
</li>
<li><p>명령어 사이클(Instruction cycle)</p>
<ul>
<li>CPU 하나의 명령을 실행하는 과정. CPU는 전원이 켜진 후 단순하게 명령 사이클 반복</li>
</ul>
</li>
<li><p>명령어 사이클 사례 : 메모리 100번지에 저장된 다음 명령을 실행하는 사례</p>
</li>
</ul>
<p>2) 명령 처리 과정 예시 </p>
<pre><code>- mov eax, [300] ; 메모리 300 번지 값을 읽어 eax 레지스터에 저장</code></pre><p><img src="https://velog.velcdn.com/images/passion_man/post/14e7c2b4-4db2-4da4-b1d2-753ac6098920/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>1) CPU는 PC 레지스터가 가리키는 주소(100)을 주소 버스에 싣는다.
2) 메모리는 100번지에 저장된 데이터(mov eax, [300])을 데이터 버스에 싣는다.
3) CPU는 데이터 버스에 담긴 바이너리 값들은 IR 레지스터에 저장. PC는 다음 번지로 수정한다.
4) CPU는 연산에 필요한 데이터를 읽기 위해 데이터의 주소(300)을 주소 버스에 싣는다.
5) 메모리는 300번지에 저장된 50을 데이터 버스에 싣는다.
6) CPU는 데이터 버스로부터 50을 임시 데이터 레지스터에 저장한다.
7) 이제 CPU는 명령을 해석하고 명령을 실행한다. 명령 실행 결과, 50이 eax 레지스터에 저장된다.</p>
<h2 id="스택은-어디-있는가">스택은 어디 있는가?</h2>
<blockquote>
</blockquote>
<p>프로그램이 실행되기 위해 운영체제에 의해 메모리에 할당되는 4개 공간
    - 코드 공간 - 프로그램 코드 적재
    - 데이터 공간 - 전역 변수들이 적재되는 공간
    - 힙 공간 - 프로그램 동적으로 저장할 데이터를 위한 공간
    - 스택 공간 - 함수가 호출될 때 매개변수, 지역변수 등 저장</p>
<ul>
<li><p>스택 : 운영체제에 의해 프로그램마다 메모리에 할당된 일부 영역</p>
<ul>
<li><p>스택이라는 별도의 하드웨어 메모리가 있는 것은 아님</p>
</li>
<li><p>메모리의 일부를 스택으로 사용하도록 할당된 공간</p>
</li>
<li><p>각 프로그램에게 자신만의 스택 공간 할당</p>
</li>
<li><p>CPU의 SP 레지스터가 현재 프로그램의 스택 꼭대기 주소를 가리킴</p>
</li>
<li><p>스택에 저장되는 내용</p>
</li>
<li><p>함수의 지역변수들</p>
</li>
<li><p>함수가 호출될 때 전달받은 매개변수 값들</p>
</li>
<li><p>함수를 실행한 후 돌아갈 주소</p>
</li>
<li><p>함수 코드가 의도적으로 저장해 두기 위한 값</p>
<h2 id="컨택스트">컨택스트</h2>
</li>
</ul>
</li>
<li><p>컨텍스트 : 프로그램이 실행 중인 일체의 상황 혹은 상황 정보 -&gt; 메모리 (프로그램 코드와 데이터, 스택, 동적할당 받아 저장한 값)</p>
<ul>
<li>CPU 레지스터들의 값    </li>
<li>PC에는 코드의 주소<ul>
<li>SP에는 스택의 주소</li>
<li>다른 레지스터는 이전의 실행 결과나 현재 실행에 사용될 데이터들</li>
</ul>
</li>
</ul>
</li>
<li><p>축소정의 : 현재 CPU에 들어 있는 레지스터들의 값들</p>
</li>
<li><p>컨텍스트 스위칭</p>
<ul>
<li><p>현재 실행중인 프로그램의 컨텍스트(CPU레지스터들의 값)를 저장</p>
</li>
<li><p>다른 프로그램의 저장된 컨텍스트(CPU레지스트들의 값)를 CPU에 복귀</p>
</li>
<li><p>발생</p>
</li>
<li><p>CPU가 현재 프로그램 실행을 중지하고 다른 프로그램을 실행할 때</p>
<h2 id="멀티코어-cpu">멀티코어 CPU</h2>
</li>
</ul>
</li>
<li><p>2001년 IBM에 의해 PowerPC라는 멀티코어 CPU 개발</p>
<ul>
<li>CPU 내부에 2개의 프로세서 포함</li>
<li>2개의 프로그램을 동시에 실행<ul>
<li>코어는 완벽한 처리기, 과거 개념의 CPU<h1 id="컴퓨터-시스템과-운영체제">컴퓨터 시스템과 운영체제</h1>
<h2 id="컴퓨터-시스템이-계층-구조로-설계된-이유">컴퓨터 시스템이 계층 구조로 설계된 이유</h2>
: 계층 간 독립성 확보를 위해</li>
</ul>
</li>
</ul>
</li>
<li><p>사용자 : 운영체제나 하드웨어에 대해 몰라도 응용프로그램으로 컴퓨터 활용 가능</p>
</li>
</ul>
<p>1) 응용프로그램</p>
<ul>
<li>컴퓨터 하드웨어 타입이나 구조, 제어 방법을 몰라도 개발 가능<ul>
<li>CPU 크기, 메모리 크기가 얼마인지 모르고 프로그램 작성</li>
<li>저장 장치가 하드디스크인지 SSD인지, 저장 장치의 크기는 얼마인지, 디스크 헤드는 몇 개 있는지 몰라도 파일 입출력 프로그램 작성</li>
</ul>
</li>
<li>운영체제에게 요청하여 해결</li>
<li>컴퓨터 하드웨어가 바뀌어도 응용프로그램을 다시 작성할 필요 없음</li>
</ul>
<p>2) 운영체제</p>
<ul>
<li><p>운영체제는 장치 관련된 모든 작업을 디바이스 드라이버에게 요청</p>
</li>
<li><p>응용프로그램과 하드웨어 사이의 인터페이스</p>
<h2 id="왜-운영체제가-필요한가">왜 운영체제가 필요한가?</h2>
</li>
<li><p>운영체제가 없다면</p>
<ul>
<li>응용프로그램이나 사용자가 직접 하드웨어를 제어해야 함</li>
<li>하드웨어에 대한 지식, 충돌, 관리, 보안의 문제 발생</li>
</ul>
</li>
<li><p>운영체제의 필요성 : 자원에 대한 충돌 해결, 성능 최적화, 사용자의 시스템 사용의 효율화</p>
<h2 id="운영체제와-응용프로그램-사이의-관계">운영체제와 응용프로그램 사이의 관계</h2>
<p>1) 응용프로그램</p>
</li>
<li><p>워드, 웹브라우저 등 사용자가 컴퓨터를 활용하도록 작성된 다양한 프로그램들</p>
</li>
</ul>
<p>2) 응용프로그램에 대한 운영체제의 역할</p>
<ul>
<li>응용프로그램이 직접 하드웨어를 다루지 못하도록 차단<ul>
<li>운영체제가 하드웨어 완벽히 독점 장악</li>
<li>이유 : 응용프로그램들 사이의 하드웨어 사용 충돌을 막기 위함</li>
</ul>
</li>
</ul>
<p>3) 응응프로그램은 하드웨어를 사용하고자 할 때</p>
<ul>
<li>반드시 운영체제에게 요청 -&gt; 운영체제가 대신하여 하드웨어 조작</li>
<li>유일한 요청 방법 : 시스템 호출</li>
</ul>
<p>4) 응용프로그램과 하드웨어 사이의 인터페이스</p>
<p>5) 응용프로그램들의 실행 순서 제어</p>
<p>6) 응용프로그램들 사이의 통신 중계</p>
<h2 id="운영체제와-사용자의-관계">운영체제와 사용자의 관계</h2>
<ul>
<li><p>사용자는 응용프로그램을 통해 컴퓨터 활용 : 탐색기, 메모장 등</p>
</li>
<li><p>사용자에 대한 운영체제의 역할</p>
<ul>
<li>사용자가 하드웨어에 관한 지식이 없어도 컴퓨터 다루기 용이</li>
<li>사용자가 하드웨어를 설치하거나 변경하는 것에 도움</li>
<li>사용자에게 컴퓨터 시스템을 사용할 때 편리한 인터페이스 제공 ( UI, 마우스, 음성 명령 등 )</li>
<li>컴퓨터의 사용을 돕는 여러 도구 응용프로그램(유틸리티) 제공 ( Windows 의 탐색기와 작업관리자 )</li>
<li>사용자 계정관리</li>
<li>사용자의 컴퓨터 사용 시간 계산, 과금 처리 등</li>
</ul>
</li>
</ul>
<h2 id="운영체제와-하드웨어의-관계">운영체제와 하드웨어의 관계</h2>
<ul>
<li><p>하드웨어를 제어하는 것은 전적으로 운영체제의 몫</p>
<ul>
<li>응용프로그램에서 printf(&quot;hello&quot;) : 디스플레이 장치에 &quot;hello&quot;를 출력하는 일을 운영체제가 함</li>
<li>응용프로그램에서 scanf() : 키보드로부터 문자를 입력받는 일은 운영체제가 함<h2 id="운영체제">운영체제</h2>
</li>
</ul>
</li>
<li><p>운영체제</p>
<ul>
<li>사용자/응용프로그램과 하드웨어 사이의 매개체</li>
<li>하드웨어 제어는 전적으로 운영체제의 기능<ul>
<li>하드디스크에서 파일을 읽거나 쓰기</li>
<li>마우스의 클릭</li>
<li>키보드의 입력 받기</li>
<li>네트워크를 통한 데이터 전송 혹은 수신<ul>
<li>디스플레이에 텍스트나 이미지, 그래픽 등 출력</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>운영체제의 전체기능</p>
</li>
</ul>
<p>1) 프로세스와 스레드 관리</p>
<ul>
<li>프로세스/스레드의 실행, 일시 중단, 종료, 스케줄링, 컨텍스트 스위칭, 동기화</li>
</ul>
<p>2) 메모리 관리</p>
<ul>
<li>프로세스나 스레드에게 메모리 할당, 메모리 반환, 다른 프로세스/스레드로부터 메모리 보호</li>
<li>메모리를 하드 디스크의 영역까지 확장하는 가상 메모리 기술</li>
</ul>
<p>3) 파일 관리 혹은 파일 시스템 관리</p>
<ul>
<li>파일 생성, 저장, 읽기, 복사, 삭제, 이동, 파일 보호</li>
</ul>
<p>4) 장치 관리</p>
<ul>
<li>키보드, 마우스, 프린터 등 입출력 장치, 하드 디스크 등 저장 장치 제어</li>
<li>입출력</li>
</ul>
<p>5) 사용자 인터페이스</p>
<ul>
<li>라인 기반 명령 입출력 창, 마우스와 그래픽 사용 GUI 인터페이스</li>
</ul>
<p>6) 네트워킹</p>
<ul>
<li>네트워크 인지, 연결, 닫기, 데이터 송수신</li>
</ul>
<p>7) 보호 및 보안</p>
<ul>
<li>바이러스나 웜, 멀웨어, 해킹 등의 외부 공격이나 무단 침입으로부터 보호 </li>
</ul>
<p>운영체제의 구성 요소와 커널
<img src="https://velog.velcdn.com/images/passion_man/post/0a05b0e3-70dd-4d0c-ad4f-3918240d1a26/image.png" alt=""></p>
<p>운영체제 구성</p>
<blockquote>
<p>운영체제 = 커널 + 툴 + 디바이스 드라이버</p>
</blockquote>
<p>1) 커널</p>
<ul>
<li>운영체제의 핵심 부분, 좁은 의미의 운영체제</li>
<li>부팅 후 메모리에 상주하는 코드와 데이터</li>
<li>커널 코드는 함수들의 집합의 구성</li>
<li>커널 기능을 이용하려면 응용프로그램은 반드시 시스템 호출을 사용</li>
</ul>
<p>2) 도구(tool) 소프트웨어와 GUI</p>
<ul>
<li>사용자가 컴퓨터를 편리하게 사용할 수 있도록 제공하는 툴 소프트웨어 혹은 툴 응용프로그램</li>
<li>Windows 경우, 바탕화면 GUI, 탐색기, 명령창, 작업 관리자, 제어판</li>
</ul>
<p>3) 디바이스 드라이버</p>
<ul>
<li>장치를 직접 제어하고 입출력하는 소프트웨어</li>
<li>장치마다 전담 디바이스 드라이버 있음</li>
<li>일반적으로 장치 제작자에 의해 작성되어 배포됨</li>
<li>사례 : 키보드 드라이버, 디스크 드라이버, SCSI 드라이버, 마우스 드라이버, 그래픽 드라이버, 네트워크 드라이버 ...</li>
</ul>
<p>** 운영체제 커널 인터페이스 : 시스템 호출과 인터럽트</p>
<h2 id="시스템-호출">시스템 호출</h2>
<ul>
<li><p>커널과 응용프로그램 사이의 인터페이스</p>
</li>
<li><p>응용프로그램에서 커널 기능을 사용할 수 있는 유일한 방법</p>
<ul>
<li>시스템 호출 라이브러리를 통해 다양한 시스템 호출 함수 제공</li>
<li>예 : open(), close(), read(), write(), fork(), exit(), wait() 등의 시스템 함수 호출</li>
</ul>
</li>
</ul>
<h2 id="인터럽트">인터럽트</h2>
<ul>
<li><p>커널과 하드웨어 장치 사이의 인터페이스</p>
</li>
<li><p>장치들이 입출력 완료, 타이머 완료 등을 CPU에게 알리는 하드웨어적 방법 (인터럽트 하드웨어 신호가 직접 CPU에 전달)</p>
</li>
<li><p>CPU는 하는 일을 중단하고 인터럽트 서비스 루틴 실행</p>
<ul>
<li>인터럽스 서비스 루틴은 커널이 적재된 메모리 영역에 있는 코드</li>
<li>인터럽트 서비스 루틴은 일반적으로 디바이스 드라이버 내에 있음
예 : 키를 입력하면 커널의 키보드 인터럽트 서비스 루틴 실행, 키를 읽어 커널 버퍼에 저장</li>
<li>인터럽트 서비스 루틴의 실행을 마치면 하던 작업 계속</li>
</ul>
</li>
<li><p>인터럽트 활용</p>
<ul>
<li>운영체제가 장치에게 지시한 입출력 작업의 완료, 예고 없는 네트워크 데이터의 도착, 키모드나 마우스의 입력, 부족한 배터리의 경고등 장치와 관련된 모든 이벤트 처리<h1 id="커널과-시스템-호출">커널과 시스템 호출</h1>
<h2 id="응용프로그램의-자원-접근-문제">응용프로그램의 자원 접근 문제</h2>
</li>
</ul>
</li>
<li><p>오늘 날 운영체제는 다중프로그래밍 운영체제</p>
<ul>
<li>응용프로그램이 직접 컴퓨터 자원에 접근하면 충돌과 훼손 발생</li>
</ul>
</li>
<li><p>다른 응용프로그램이 적재된 메모리 훼손 가능</p>
</li>
<li><p>다른 응용프로그램이 만든 파일 삭제 및 훼손 가능</p>
</li>
<li><p>응용 프로그램이 커널이 적재된 영역 훼손 가능</p>
</li>
</ul>
<p>해결책</p>
<ul>
<li>응용프로그램의 자원 접근 불허</li>
<li>메모리 공간을 사용자 공간과 커널 공간으로 분리</li>
<li>CPU의 실행 모드를 사용자 모드와 커널 모드로 분리<ul>
<li>응용프로그램은 사용자 모드에서만 실행</li>
<li>커널 코드는 커널 모드에서만 실행</li>
<li>사용자 모드에서 커널 코드를 접근하면 응용프로그램 강제 종료<h2 id="사용자-공간과-커널-공간">사용자 공간과 커널 공간</h2>
</li>
</ul>
</li>
<li><ul>
<li>운영체제는 컴퓨터 메모리를 두 공간으로 분리</li>
</ul>
</li>
<li>사용자 공간 : 모든 응용프로그램들이 나누어 사용하는 공간 (응용프로그램들이 적재되는 공간)</li>
<li>커널 공간 : 커널만 사용할 수 있는 공간<ul>
<li>커널 코드, 커널 데이터 등 커널에 의해 배타적으로 사용되는 공간</li>
<li>디바이스 드라이버 포함</li>
</ul>
</li>
</ul>
<p>사용자 공간 크기</p>
<ul>
<li><p>한 응용프로그램의 최대 크기</p>
<ul>
<li>프로그램 코드 + 데이터(전역변수) + 동적할당 + 스택을 합친 크기
예 : 32비트 Windows 운영체제에서 사용자 공간 2GB -&gt; 응용프로그램의 크기가 최대 2GB</li>
</ul>
</li>
<li><p>사용자 공간의 주소 범위</p>
<ul>
<li>응용프로그램은 운영체제가 설정한 사용자 공간의 주소 범위를 넘어설 수 없음<h2 id="주소-공간은-가상-주소-공간">주소 공간은 가상 주소 공간</h2>
<img src="https://velog.velcdn.com/images/passion_man/post/72dd47f4-9f65-40ee-ad31-f179587c45c1/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/28a694b0-3959-4702-b7f6-6e12fdba7f7b/image.png" alt=""></li>
</ul>
</li>
</ul>
<blockquote>
</blockquote>
<p>[참고]
Memory Management는 CPU가 가상주소체계를 통해 실제물리주소에 존재하는 프로그램을 읽고 실행시키기 위해 필요한 과정을 관리해주는 알고리즘을 말한다. 만약 MMU가 지원되지 않으면 물리메모리에 직접 접근해서 프로그램을 동작시켜야 하기 때문에, 가상메모리만으로도 물리 메모리를 신경쓰지 않고 해결할 수 있도록 해주는 것이 MMU이다.</p>
<blockquote>
</blockquote>
<p>가상메모리를 통해 우리는 우리에게 실제로 할당된 물리메모리 이상을 사용할 수도 있고, 또한 메모리를 어떻게 할당해주어야 할지에 대한 고민없이 프로그래밍을 할 수 있다. 즉, 아래 3가지가 가능해진다.</p>
<p>1) 사용자가 기억장소를 일일이 할당하는 불편을 없애준다.
2) 프로세스의 크기가 실제 메모리의 총량을 초과해도 사용할 수 있다.
3) 설사 물리적 메모리의 용량이 충분히 크다고하더라도 다중 프로그래밍이 가능하다.</p>
<blockquote>
</blockquote>
<p>그러니까, 실제적으로 각 프로그램의 일부만이 메모리로 계속 올라가는 것이므로, 어느 시점에서 보면 프로세스의 개수는 많다고 하지만, 실제로 메모리로 올라가는 크기의 총합은 결코 메모리를 초과하지 않는다. 그렇지 만들지 않는다. 설사 메모리가 가득차게 된다고 하더라도 swapping 기술이 적용되어 해결된다.</p>
<blockquote>
<p>RAM 공간이 부족할 때 HDD에 파일 형태로 따로 확장하는 가상 메모리 공간</p>
</blockquote>
<h2 id="사용자-모드와-커널-모드">사용자 모드와 커널 모드</h2>
<p>** CPU는 사용자 모드와 커널 모드 중 한 모드로 실행 (CPU 내부에는 모드 상태를 나타내는 모드 레지스터가 있음)</p>
<p>1) 사용자 모드</p>
<ul>
<li>CPU의 모드 비트 = 0</li>
<li>CPU는 사용자 공간에 있는 코드나 데이터를 액세스 하는 중</li>
<li>CPU의 커널 공간 접근 불허 -&gt; 응용프로그램으로부터 커널 영역 보    호</li>
<li>특권 명령 실행 불허</li>
</ul>
<p>** 특권 명령 : 입출력 장치 등 하드웨어나 시스템 중단 등 시스템 관련 처리를 위해 설계된 특별한 명령</p>
<p>2) 커널 모드</p>
<ul>
<li>CPU의 모드 비트 = 1</li>
<li>CPU가 커널 공간에서 실행하는 중, 혹은 사용자 코드를 실행하는     중<ul>
<li>특권 명령 사용 가능</li>
</ul>
</li>
</ul>
<p>3) 사용자 모드에서 커널 모드로 변경되는 경우</p>
<ul>
<li>시스템 호출과 인터럽트 발생의 2가지 경우에만 변경</li>
<li>시스템 호출 과정은 커널 모드로 변경하는 특별한 기계 명령 사용<ul>
<li>CPU의 &#39;모드 레지스터&#39;의 값을 커널 모드로 수정</li>
<li>int 0x80/sysenter/trap/syscall 등 CPU 마다 다름</li>
</ul>
</li>
</ul>
<table>
<thead>
<tr>
<th align="center"></th>
<th>사용자모드</th>
<th>커널모드</th>
</tr>
</thead>
<tbody><tr>
<td align="center">CPU의 메모리 액세스 범위</td>
<td>사용자 공간에 국한, 커널 공간 액세스 불가</td>
<td>커널 공간을 포함한 모든 메모리 공간</td>
</tr>
<tr>
<td align="center">CPU의 하드웨어 액세스 여부</td>
<td>불가</td>
<td>모든 하드웨어 액세스 가능</td>
</tr>
<tr>
<td align="center">CPU가 처리 가능한 명령</td>
<td>특권 명령을 제외한 모든 CPU 명령</td>
<td>특권 명령을 포함한 모든 CPU 명령</td>
</tr>
<tr>
<td align="center">오류 발생 시 처리</td>
<td>사용자 프로그램만 실행 종료. 시스템이 종료되지 않으므로 안전</td>
<td>시스템에 심각한 오류가 발생한 것으로 시스템 종료</td>
</tr>
</tbody></table>
<h2 id="특권-명령">특권 명령</h2>
<p>** 특권 명령 : 커널 모드에서 실행할 특별한 목적으로 설계된 CPU 명령</p>
<ul>
<li>특권 명령 종류 ( 운영체제만 할 수 있는 것들 )</li>
</ul>
<p>1) I/O 명령</p>
<ul>
<li>하드웨어 제어 및 장치로부터의 입출력
예 : in eax, 300 : I/O 포트 300번지에서 값을 읽어 eax 레지스터에 저장
out 301, eax : eax 레지스터에 있는 값을 I/O 포트 301번지에 쓰기</li>
</ul>
<p>2) Halt 명령</p>
<ul>
<li>CPU의 작동을 중지 시키는 명령. CPU를 유휴 상태로 만듬</li>
</ul>
<p>3) 인터럽트 플래크 켜고 끄는 명령</p>
<ul>
<li>CPU 내에 있는 인터럽트 플래그 비트를 제어하여 CPU가 인터럽트를 허용하거나 무시하도록 지시
예 : cli / sti 명령</li>
</ul>
<p>4) 타이머 설정 명령</p>
<p>5) 컨텍스트 스위칭 명령</p>
<p>6) 메모리 지우기 명령</p>
<p>7) 장치 상태 테이블 수정 등의 명령</p>
<h2 id="실행-모드와-관련된-다양한-이슈">실행 모드와 관련된 다양한 이슈</h2>
<ol>
<li>사용자 모드와 커널 모드는 CPU의 기능인가 아니면 운영체제의 기능인가?</li>
</ol>
<ul>
<li>모드는 CPU의 기능이다.</li>
<li>CPU 내부에 모드를 나타내는 레지스터 존재</li>
<li>운영체제는 CPU 모드 레지스터를 이용하여 커널 영역 지킴</li>
</ul>
<ol start="2">
<li>사용자 응용프로그램이 커널 코드를 호출할 일이 있는가?</li>
</ol>
<ul>
<li>사용자 응용프로그램은 직접 커널 코드 호출 불가</li>
<li>시스템 호출을 통해서만 가능</li>
</ul>
<ol start="3">
<li>CPU가 평균적으로 커널 모드에서 많이 실행될까 사용자 모드에서 많이 실행될까?</li>
</ol>
<ul>
<li>커널 모드에서 많이 실행</li>
</ul>
<ol start="4">
<li>운영체제가 사용자 모드와 커널 모드로 나누어 작동시키는 이유는?</li>
</ol>
<ul>
<li>커널공간에 대한 보안과 보호</li>
<li>악의적 사용자와 오류 프로그램으로 커널 공간 지킴</li>
<li>사용자 응용프로그램은 사용자 모드에서 아무리 심각한 오류가 발생해도 사용자 프로그램만 종료. 시스템을 중단시키는 못함</li>
</ul>
<h2 id="커널">커널</h2>
<p>** 커널의 실체</p>
<ul>
<li><p>커널은 부팅 시에 커널 공간에 적재 함수들과 데이터의 집합</p>
<ul>
<li>커널은 컴파일된 바이너리 형태, 하드디스크 특정 영역에 저장</li>
<li>부팅 시에 커널 공간의 메모리에 적재</li>
</ul>
</li>
<li><p>커널 코드는 함수들의 집합</p>
</li>
</ul>
<ol>
<li>커널은 스스로 실행되는 프로세스인가? NO</li>
</ol>
<ul>
<li>커널은 단순함수들의 집합, 시스템 호출을 통해 호출되는 함수들</li>
<li>커널이 스케줄링한다 ( X )<ul>
<li>커널 프로세스가 실행되면서 주기적으로 스케줄링 하는게 아니고 시스템 호출과 인터럽트 서비스 루틴에 의해 필요한 경우 스케줄러 함수 실행</li>
</ul>
</li>
</ul>
<ol start="2">
<li>커널은 실행 중이다? NO</li>
</ol>
<ul>
<li>커널은 프로세스도 스레드도 아니므로 NO</li>
<li>커널이 실행 중인 게 아니고 응용프로그램이 시스템 호출을 실행하면 커널 코드가 실행되는 것</li>
<li>인터럽트가 발생하면 인터럽트 서비스 루틴이 실행</li>
</ul>
<ol start="3">
<li>커널은 스택이나 힙을 가지는가? NO</li>
</ol>
<ul>
<li><p>프로세스나 스레드가 스택이나 힙 소유함</p>
</li>
<li><p>커널 공간에 스레드를 위한 스택이 만들어진다. 스레드가 커널 코드를 실행하고 있을 때 커널 스택 형성</p>
</li>
<li><p>커널의 존재</p>
<ul>
<li>커널은 스스로 실행되는 코드(프로세스)가 아님</li>
</ul>
</li>
<li><p>커널이 스케줄링 한다 -&gt; (커널 속의)스케줄링 함수가 실행된다.
<img src="https://velog.velcdn.com/images/passion_man/post/8796443f-e2ec-47b2-91c3-f6da652be32c/image.png" alt=""></p>
</li>
</ul>
<h2 id="응용프로그램-빌딩">응용프로그램 빌딩</h2>
<ul>
<li>라이브러리<ul>
<li>응용프로그램에서 활용하도록 미리 함수들을 작성하여 컴파일하고 바이너리 형태로 만든 파일
( 바이너리 형태면 CPU 가 바로 이해할 수 있어서 Memory 에 탑재했을 때 바로 사용 가능하다 )</li>
<li>라이브러리를 활용하지 않고 응용프로그램 작성이 불가능</li>
</ul>
</li>
</ul>
<p>-응용프로그램이 활용하는 라이브러리는 2가지 유형</p>
<ol>
<li>표준 라이브러리</li>
</ol>
<ul>
<li>운영체제나 컴퓨터 하드웨어에 상관없이 이름과 사용법 동일</li>
<li>사용자가 작성하기 힘든 함수 제공</li>
</ul>
<ol start="2">
<li>시스템 호출 라이브러리</li>
</ol>
<ul>
<li>시스템 호출을 진행하여 커널 모드로 바꾸고 커널로 진입하여 커널에 만들어진 함수 실행 ( 커널의 다양한 기능 수행 )</li>
<li>운영체제마다 함수의 이름이 서로 다름</li>
<li>커널 API(Application Programming Interface) 라고도 부름<h2 id="함수-호출과-시스템-호출">함수 호출과 시스템 호출</h2>
</li>
</ul>
<p>1) 함수 호출</p>
<ul>
<li><p>사용자 공간에 적재된 함수가 다른 함수나 라이브러리 함수 호출</p>
</li>
<li><p>사용자 공간에서, 사용자 모드에서 실행</p>
</li>
<li><p>실행 과정</p>
<ul>
<li>사용자 공간의 스택에 돌아올 주소, 매개변수 전달, 호출된 함수의 지역변수 생성</li>
<li>호출된 함수가 끝나면 함수를 호출한 곳으로 복귀</li>
</ul>
</li>
</ul>
<p>2) 시스템 호출</p>
<ul>
<li><p>응용프로그램이 운영체제의 기능을 사용하고자 하는 경우</p>
</li>
<li><p>커널에 작성된 함수를 실행하고자하는 경우</p>
</li>
<li><p>시스템 호출 라이브러리에서 커널 기능 요청</p>
</li>
<li><p>사용자 모드에서 커널 모드로 변경된 후 커널 함수 실행</p>
</li>
<li><p>실행 과정</p>
<ul>
<li>시스템 호출을 일으키는 특별한 기계 명령 실행 ( 커널 함수마다 매겨진 고유 번호 전달, 사용자 모드에서 커널 모드로 변경 )</li>
<li>커널의 시스템 호출 핸들러 실행 ( 이 핸들러가 커널 함수의 고유 번호를 분석하여 해당 커널 함수 호출 )</li>
</ul>
</li>
</ul>
<table>
<thead>
<tr>
<th></th>
<th>함수 호출</th>
<th>시스템 호출</th>
</tr>
</thead>
<tbody><tr>
<td>메모리 영역</td>
<td>사용자 영역의 코드에서 사용자 영역의 함수 호출</td>
<td>사용자 영역의 코드에서 커널 함수 호출</td>
</tr>
<tr>
<td>CPU 실행 모드</td>
<td>사용자 모드</td>
<td>사용자 모드에서 커널 모드로 전환</td>
</tr>
<tr>
<td>비용</td>
<td>함수 호출에 따른 비용</td>
<td>커널 모드로 전환하는 등 함수 호출에 비해 큰 비용</td>
</tr>
<tr>
<td><img src="https://velog.velcdn.com/images/passion_man/post/1d4d0270-29cd-4153-a68e-f4b7b8dab07a/image.png" alt=""></td>
<td></td>
<td></td>
</tr>
</tbody></table>
<h2 id="시스템-호출-1">시스템 호출</h2>
<p>1) 시스템 호출</p>
<ul>
<li><p>사용자 공간의 코드에서 커널 서비스를 요청하는 과정</p>
<ul>
<li>사용자 공간의 코드가 커널 함수를 호출하는 과정</li>
<li>커널 콜, 트랩으로도 불림</li>
<li>응용프로그램에서 커널 기능을 활용하도록 만들어놓은 기능</li>
</ul>
</li>
<li><p>시스템 호출 라이브러리 제공</p>
<ul>
<li>시스템 호출 함수 혹은 커널 API</li>
<li>Unix/Linux 의 커널 API - open(), read(), write(), fork(), exit()</li>
<li>Windows의 커널 API - CreateProcess(),     WaitForSinlgeObject()</li>
<li>대략 200개 이상</li>
</ul>
</li>
<li><p>시스템 호출을 일으키는 기계 명령</p>
</li>
</ul>
<p>CPU마다 시스템 호출을 실행하는 특별한 기계 명령 제공</p>
<p>2) 사례</p>
<ul>
<li>int 0x80 - 인텔의 x86 계열의 CPU, 32비트에서 사용</li>
<li>syscall/sysret - ADM에서 최초 구현, 64비트에서만 작동</li>
<li>sysenter/sysexit - Intel 에서 최초 구현, X86/64 CPU, AMD</li>
</ul>
<p>3) 라이브러리를 통해 간접적으로 이루어지는 시스템 호출</p>
<ul>
<li>응용프로그램 -&gt; 시스템 호출 라이브러리의 시스템 호출 함수 -&gt; 시스템 호출 CPU 명령</li>
<li>응용프로그램 -&gt; 표준 라이브러리 함수 -&gt; 시스템 호출 라이브러리의 시스템 호출 함수 -&gt; 시스템 호출 CPU 명령
<img src="https://velog.velcdn.com/images/passion_man/post/d0538bf5-7fcb-4a74-b527-6c336bf0e69f/image.png" alt=""></li>
</ul>
<h2 id="printf-가-직접-디스플레이에-출력할까">printf() 가 직접 디스플레이에 출력할까?</h2>
<ul>
<li>printf() 함수는 표준 라이브러리 함수이다.</li>
<li>printf() 함수를 호출하면 시스템 호출이 일어날까?<ul>
<li>디스플레이에 접근하는 것은 커널만 가능</li>
<li>printf() 함수는 디스플레이에 직접 출력 불가능</li>
<li>printf()는 C 표준 라이브러리의 버퍼에 출력</li>
<li>버퍼가 꽉 차 있으면 printf()는 시스템 호출 함수 write() 함수 호출 ( printf() 함수가 시스템 호출 함수인 write() 함수 호출해서 운영체제(커널)에 의해서 디스플레이에 출력 )</li>
<li>write() 함수는 &#39;시스템 호출 CPU 명령&#39; 실행</li>
<li>커널에 작성된 함수가 디스플레이에 &quot;hello&quot; 출력</li>
</ul>
</li>
</ul>
<blockquote>
</blockquote>
<p>[참고 : 버퍼의 개념]</p>
<ul>
<li>단순히 메모리상에 있는 값을 화면에 바로 출력하거나 입력한 값을 메모리상에 바로 저장하기전에 겉으로 보이지않는 *버퍼(buffer) *라는 것을 통하게 된다. 버퍼란 사전적의미 그대로 데이터 전송시 양쪽의 속도차를 보완하기 위해 만들어진 개념이다. 버퍼가 없다면 컴퓨터는 바이트단위로 데이터를 읽거나 출력하기위해 메모리에 접근하는 횟수가 엄청나게 늘어나게되고 CPU에도 부하가 많이 걸리게 될 것이다. 그래서 버퍼라는 공간에 입출력할만큼 데이터를 받아놓고 전송하게 되는 것이다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/b78c4c0a-586d-4d51-9454-a9309a41b107/image.png" alt=""></p>
<h2 id="시스템-호출-비용--fread-와-read-의-비교">시스템 호출 비용 : fread() 와 read() 의 비교</h2>
<ul>
<li><p>시스템 호출은 함수 호출에 비해 많은 시간 비용</p>
<ul>
<li>시스템 호출을 많이 할 수록 프로그램 실행 속도 저하</li>
</ul>
</li>
<li><p>파일에서 100바이트를 읽는 2가지 유형의 코드. 실행 비교 결과는?</p>
</li>
</ul>
<p>1) 함수 호출 fread()와 시스템 호출 read() 비교</p>
<ul>
<li><p>표준 라이브러리 함수, fread(fp, buf, size) 동작</p>
<ul>
<li>fread() 를 처음 호출하면 라이브러리 내 버퍼가 비어 있음</li>
<li>read() 를 호출하여 라이브러리 내 버퍼를 채운다</li>
<li>라이브러리 버퍼에서 요청한 size 만큼 buf 로 복사한다.</li>
<li>라이브러리 버퍼가 비거나 부족하면 그때 read() 호출</li>
</ul>
</li>
<li><p>시스템 호출 함수, read(fd, buf, size) 동작</p>
<ul>
<li>시스템 호출을 이용하여 커널 코드 실행</li>
<li>커널 코드에서 디스크 읽기</li>
<li>라이브러리를 거치지 않고 바로 buf로 읽어들임</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/ab313acf-1ebb-43f5-852e-42245cec0053/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/24beec24-b0a4-4927-ad70-51a569ed1b2b/image.png" alt=""></p>
<h1 id="운영체제와-인터럽트">운영체제와 인터럽트</h1>
<h2 id="인터럽트-1">인터럽트</h2>
<p>** 인터럽트 : CPU가 현재 하는 일을 중단하고 다른 일을 하도록 시키는 비동기적 방법</p>
<p>1) 하드웨어 인터럽트</p>
<ul>
<li>장치들이 어떤 상황 발생을 CPU에게 알리는 하드웨어 신호</li>
<li>인터럽트 발생 -&gt; CPU는 인터럽트 서비스 루틴 실행</li>
</ul>
<p>2) 소프트웨어 인터럽트</p>
<ul>
<li>CPU 명령어에 의해 하드웨어 인터럽트를 수신한 것과 동일한 처리</li>
</ul>
<p>3) 컴퓨터에서 인터럽트 활용</p>
<ul>
<li>마우스를 움직이거나 클릭하는 등 마우스 조작</li>
<li>키보드 입력</li>
<li>네트워크로부터 데이터 도착</li>
<li>하드디스크의 쓰기 종료</li>
<li>시스템 클럭으로부터 일정한 시간 간격으로 알림</li>
<li>컴퓨터의 리셋 버튼 누르기</li>
<li>USB 메모리 부착 혹은 해제</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/168fcbde-90c9-4172-bcba-6a5a0b0dc464/image.png" alt=""></p>
<h2 id="인터럽트-서비스-루틴">인터럽트 서비스 루틴</h2>
<p>** 인터럽트 핸들러라고도 부른다.
위치 : 디바이스 드라이버나 커널 코드, 임베디드 컴퓨터 ROM</p>
<h2 id="인터럽트는-다중프로그래밍의-key">인터럽트는 다중프로그래밍의 key</h2>
<ul>
<li><p>다중 프로그래밍이란?</p>
<ul>
<li><p>여러 프로세스를 동시에 실행</p>
</li>
<li><p>한 프로세스가 입출력을 시행하면 다른 프로세스로 교체 실행</p>
</li>
<li><p>입출력이 완료될 때, 장치로부터 입출력 완료 통보를 받는 방법 필요 -&gt; 인터럽트</p>
<ul>
<li>입출력 완료를 계속 검사하는 폴링(Polling)방법은 CPU에 의해 이루어지므로 매우 비효율적 (반면 인터럽트는 CPU가 아니라 디바이스 드라이버에서 이루어짐)</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>이 글이 문제가 된다면 삭제하겠습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[텍스트 마이닝] 14. Coreference]]></title>
            <link>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-14.-Coreference</link>
            <guid>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-14.-Coreference</guid>
            <pubDate>Tue, 24 May 2022 11:25:59 GMT</pubDate>
            <description><![CDATA[<p>Discourse </p>
<ul>
<li>Discourse covers linguistic expression beyond the boundary of the sentence -&gt; 문장의 밖에서도 의미가 전달 됨 
1) Dialogues : the structure of turns in conversation -&gt; 대화
2) Monologues : the structure of entire passages, documents -&gt; 하나의 문장이 쭉 이어진 독백</li>
</ul>
<h1 id="coreference">Coreference</h1>
<p><img src="https://velog.velcdn.com/images/passion_man/post/c5e551be-b604-4391-bcd4-8d2dc9c773f4/image.png" alt=""></p>
<p>=&gt; You!, your father, you, him, I, your father 이 각각 누구를 가르키는지를 알아내는 게 coreference 이다.</p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/53776b7c-1049-4c2a-87b5-50fcdace141e/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/f96afe0c-35b9-40f0-a9bf-befc0e7f0f88/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/649d1461-64a8-471a-9e0f-b5130532421f/image.png" alt=""></p>
<p>=&gt; she, her, it, that 등이 고유명사 entities(VICTORIA CHEN, MEGABUCKS, LOTSABUCKS) 중에서 뭐를 가리키는지 
=&gt; company, 37-year-old, president ... 등이 뭐를 가리키는지</p>
<h2 id="event-coreference">Event Coreference</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/1bcb0170-f70a-488e-b208-e268307c9bf7/image.jpg" alt=""></p>
<h2 id="verb-semantics">Verb semantics</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/a3e94adf-7c14-412c-819c-8482b2c7abdf/image.jpg" alt="">
=&gt; 지칭하는 대상이 다를 수도 있다. </p>
<h2 id="selectional-restrictions">Selectional restrictions</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/9c0d18ea-44d3-4008-90bb-1d75374b151c/image.jpg" alt="">
=&gt; 파란색 동그라미 = mention</p>
<h1 id="mention-detection">Mention Detection</h1>
<ul>
<li>Mention 후보들을 다 뽑아놓기 (고유명사 후보를 뽑기)</li>
<li>All NPs, possessive pronouns, and named entity mentions are candidate mentions. Recall is more important that precision -&gt; 재현율이 정밀도 보다 더 중요하다.</li>
</ul>
<h2 id="mention-방법--rule-base">Mention 방법 : rule-base</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/3a241a10-d26c-4cd9-af7f-0bdad7bd4e67/image.png" alt=""></p>
<p>=&gt; 여러 단계의 filter 를 거쳐서 결과를 낸다. 
=&gt; Speaker Sieve : 화자, String Match : John-John, Relaxed String Match : 애칭, Strict Head Match B,C : 같은 문장 구조</p>
<h2 id="mention-ranking-models">Mention-ranking models</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/982cfb49-29cc-4d13-a7ee-e820b81fd385/image.png" alt="">
=&gt; 처음부터 끝까지 내려가면서 link 인지 not-link인지 확인하면서 classification 한다. </p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/cd8a51bd-bcd6-41c9-b5d7-90adad86850c/image.png" alt=""></p>
<ul>
<li>The core machinery in a mention-ranking model is <strong>parameterizing</strong> the probability of a link between two mentions </li>
</ul>
<h3 id="featurized">Featurized</h3>
<p><img src="https://velog.velcdn.com/images/passion_man/post/7540cb63-5e40-4b9b-ab03-05aaa618704c/image.png" alt="">
=&gt; i : feature, a<sub>i</sub> : mention, x : input</p>
<ul>
<li>Features use information about the mention type(nominal, proper, pronoun), first/last word of mention, complete mention string, words immediately to left/right of mention, distance between mentions.</li>
<li>Decision to link to antecedent a<sub>i</sub> is based on a linear scoring function involving a set of learned weights w and a feature function f.</li>
<li>Mention 과 input의 연관성을 볼 건데, 여러 feature를 넣어주고 weight 를 조정해준다.</li>
</ul>
<h3 id="neural-coref">Neural coref</h3>
<p><img src="https://velog.velcdn.com/images/passion_man/post/cbda5df2-46d3-4254-91e7-97a1644cb5ae/image.png" alt="">
=&gt; LSTM : 순차적으로, 두 Mention이 연결됐는지 아닌지 확인한다. </p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/67c18afd-0f22-49c1-9aba-7e9090effee3/image.png" alt=""></p>
<ul>
<li>Representation for mention = <ul>
<li>BiLSTM output for first token in mention <ul>
<li>BiLSTM output for last token in mention</li>
<li>Attention over BiLSTM output for all tokens in mention</li>
<li>Features  : size of the mention</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/2db61a80-0e10-4bb6-bd83-c3d51ea1ea3f/image.png" alt=""></p>
<ul>
<li>Representaion for mention pair (mi, mj) : <ul>
<li>m<sub>i</sub> representaiton g<sub>i</sub><ul>
<li>m<sub>j</sub> representation g<sub>j</sub></li>
<li>elementwise<pre><code>  product of g&lt;sub&gt;i&lt;/sub&gt; and g&lt;sub&gt;j&lt;/sub&gt;    </code></pre><ul>
<li>Features scoped over pair : distance between m<sub>i</sub> and m<sub>j</sub></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>=&gt; LSTM의 여러 과정을 score 매겨서 softmax 로 classification 한다.</p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/2a77b72b-f4c0-49ed-ac2d-cf9628e0cb1d/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/9bc33606-1433-4f42-9003-a26cb49f943b/image.png" alt="">
=&gt; 0 ~ 8 로 갈수록 distance가 멀어짐 - 그 때마다 weight parameter </p>
<blockquote>
<p>[참고]
<img src="https://velog.velcdn.com/images/passion_man/post/1e6404c4-3cdf-49ca-b609-affa5db572e5/image.png" alt=""></p>
</blockquote>
<h2 id="evaluation">Evaluation</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/a9119649-64e0-4a70-a293-33b4cf8d8275/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/11f7dd33-40eb-4565-a0f8-7ae4dca61e5a/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/fdb0ceee-6ec3-4c19-9ba6-c317beb5dfee/image.png" alt="">
=&gt; 왼쪽이 예측, 오른쪽이 정답 -&gt; 하나씩 내려가면서 정확도/정밀도 등 평가</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[텍스트 마이닝] 12. Semantic Roles]]></title>
            <link>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-12.-Semantic-Roles</link>
            <guid>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-12.-Semantic-Roles</guid>
            <pubDate>Tue, 24 May 2022 07:46:30 GMT</pubDate>
            <description><![CDATA[<h1 id="why-is-syntax-important">Why is syntax important?</h1>
<ul>
<li>Foundation for semantic analysis </li>
</ul>
<h1 id="why-is-syntax-insufficient">Why is syntax insufficient?</h1>
<ul>
<li>syntax encodes the structure of language but doesn&#39;t directly address meaning</li>
<li>syntax alone doesn&#39;t &quot;grab&quot; in an action to take in the world</li>
</ul>
<h1 id="lexical-semantics">Lexical semantics</h1>
<ul>
<li>Vector representation that encodes information about the distribution of contexts a word appears in</li>
<li>Words that appear in similar contexts have similar representations</li>
<li>We can represent what individual words &quot;mean&quot; as a function of what other words they&#39;re related to</li>
</ul>
<blockquote>
</blockquote>
<ul>
<li>&quot;Grab&quot; = execute GrabbingFunction() -&gt; 코드화해서 의미 전달</li>
<li>&quot;the cup&quot; = object ID 9AF1948A81CD22 -&gt; representation</li>
</ul>
<h1 id="semantics">semantics</h1>
<ul>
<li>Lexical semantics is concerned with representing the meaning of words </li>
<li>Logical semantics is concerned with representing the meaning of sentences</li>
</ul>
<h1 id="meaning-representaion">Meaning representaion</h1>
<ul>
<li>A meaning representation should be unambiugous; each statement in a meaning representation should be have one meaning</li>
</ul>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/passion_man/post/89a8f0f8-8eba-4411-87e3-0e12b543bf63/image.png" alt=""></p>
<h1 id="first-order-logic-fol">First-order logic (FOL)</h1>
<ul>
<li>We want to representation every sentence as an umambiguous proposition in FOL</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/d7665a18-19cd-4b6d-bbd0-3ef28aa0a441/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/a4d6d13f-6fd5-4ba7-82a8-a1476a822003/image.png" alt=""></p>
<ul>
<li>How we map a natural language sentence to FOL is the task of semantic parsing; but we define the FOL relations and entities to be sensitive to what matters in our model</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/947b7c2d-475e-48ee-8a82-139fe9b04401/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/c9a7a1bb-3d21-42ba-abb3-8e8c7dc5dcc9/image.png" alt=""></p>
<h2 id="relations">Relations</h2>
<ul>
<li>N-art relations hold among FOL terms (constants, variables, functions) -&gt; 더 복잡하게 가능하다.
<img src="https://velog.velcdn.com/images/passion_man/post/19c4b31f-4c5c-424b-ae1c-78f653e3ca2b/image.png" alt=""></li>
</ul>
<h1 id="event-semantics">Event semantics</h1>
<p><img src="https://velog.velcdn.com/images/passion_man/post/7384ad6a-d1b9-4ab3-8097-95d5e2b3a61a/image.png" alt=""></p>
<p>[방법1]
<img src="https://velog.velcdn.com/images/passion_man/post/9df5ecfe-0cb6-4c11-81f2-6a347b6b3dd8/image.png" alt=""></p>
<p>[방법2]
<img src="https://velog.velcdn.com/images/passion_man/post/5bc41e52-b4d6-46db-9e41-4b986138b0b1/image.png" alt=""></p>
<p>[방법3]
<img src="https://velog.velcdn.com/images/passion_man/post/771ab87a-68a5-4d5e-928f-89ae4eac95c3/image.png" alt=""></p>
<h1 id="shallow-semantics">shallow semantics</h1>
<p><img src="https://velog.velcdn.com/images/passion_man/post/60628033-878c-4218-aa49-805177c563ec/image.png" alt=""></p>
<p>[뉴스 - twitter  ... 에 따라 방법이 다를 수 있다.]
<img src="https://velog.velcdn.com/images/passion_man/post/0ed38c64-672a-4edc-b195-fa2d93806bc2/image.png" alt=""></p>
<h1 id="thematic-rolse">Thematic rolse</h1>
<ul>
<li>Thematic roles capture the semantic commonality among arguments for different ralations </li>
</ul>
<blockquote>
<ul>
<li>John broke the window</li>
</ul>
</blockquote>
<ul>
<li>The window was broken by John</li>
<li><blockquote>
<p>이 두 문장은 syntax로만 보면 완전히 다른 문장이다.  </p>
</blockquote>
</li>
</ul>
<p>근데, Thematic role 까지 보면 같은 문장이다. </p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/08b956a3-ea72-4ccc-b75a-d86104d6626b/image.png" alt="">
=&gt; &quot;창문이 깨졌다&quot; 가 핵심이고 위의 features 을 이용해서 부가적인 정보를 더 붙임</p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/04edf1da-66f0-4b99-9221-62278ae0e236/image.png" alt=""></p>
<ul>
<li>Thematic roles are very useful but difficlt to formally difine AGENT, THEME, etc.</li>
<li>At the same time, they may be too coarse for som applications</li>
</ul>
<h2 id="coarsening--proto-roles">Coarsening : Proto-roles</h2>
<ul>
<li>좀 더 &#39;일반적&#39;으로 role을 부여 (피상적 Level)</li>
<li>Proto-roles = generalize thematic roles</li>
</ul>
<h1 id="2가지-data">2가지 Data</h1>
<h2 id="propbank">Propbank</h2>
<ul>
<li><p>Sentences from the Penn Treebank annotated with proto-roles, along with lexical entries for each sense of a verb identifying the specific meaning of each proto-role that verb sense </p>
</li>
<li><p>Verb-sepcific argument structures lets us map the commonalities among the different surface forms</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/5e024f21-43ea-40ee-8ab2-dfa0533d2b75/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/e72b0967-767e-46ef-a401-fedbaf0b214b/image.png" alt=""></p>
<h2 id="framenet">FrameNet</h2>
<ul>
<li><p>Propbank maps argument structure for individual verb senses</p>
</li>
<li><p>FrameNet maps argument structure for frames, which are evoked by a lexical unit</p>
</li>
<li><p>&quot;A frame is a data-structure for representing a stereotyped situation&quot; - Minsky 1975</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/fd2e5994-94fa-405e-abe4-9b25672ef121/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/b40f797b-c6c9-4b47-b5db-4693a0ebea5c/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/e5d65736-0981-48f4-9654-ccd672b7e3aa/image.png" alt=""></p>
<h3 id="semantic-frame">Semantic Frame</h3>
<p><img src="https://velog.velcdn.com/images/passion_man/post/33f6be57-2b4c-4dbf-bc5f-abc4730dd101/image.png" alt=""></p>
<p>=&gt; Lexical units 를 이용해서 Destroy 에 Frame 을 씌울 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/e019c862-97d1-4c48-b23b-36fa89cf8eee/image.png" alt="">
=&gt; 서로 같은 뜻이지만 문장 구조가 다른 두 문장에 Frame 을 씌워서 같은 문장으로 바라볼 수 있게 된다. 
=&gt; 같은 sell 과 bought 가 각 문장에서 같은 것을 의미한게 된다. </p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/20fa201c-1ae9-4fa2-a4e9-0c91b2d94a20/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[텍스트 마이닝] 11. Neural Sequence Labeling]]></title>
            <link>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-11.-Neural-Sequence-Labeling</link>
            <guid>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-11.-Neural-Sequence-Labeling</guid>
            <pubDate>Wed, 18 May 2022 04:27:04 GMT</pubDate>
            <description><![CDATA[<ul>
<li>sequence labeling 할 때, 이제는 HMM 안쓴다! RNN으로 다 할 수 있다!</li>
</ul>
<h1 id="rnns-for-pos">RNNs for POS</h1>
<ul>
<li>To make a prediction for y, RNNs condition on all input seen through time t</li>
<li>But knowing something about the future can help -&gt; BiRNN</li>
<li>BiRNN 을 가지고 POS를 수행한다.</li>
<li>data 가 최소 10만 개 정도 labeled 되어 있으면 RNN 이 더 강력해진다.</li>
<li>softmax 를 사용한다.</li>
</ul>
<blockquote>
</blockquote>
<p>[참고] - OOV 같은 경우는?</p>
<blockquote>
</blockquote>
<ul>
<li>OOV, unseen, unknown, word embedding 이 없다 ... 다 같은 의미<ul>
<li>We saw Subword information used for creationg embedding</li>
<li>Another alternative is to use standard word embeddings and reason about subword information within a model.</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/a6197473-076d-472e-8fc6-052156a7aa7c/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/6ed3c773-7b6d-4e1b-b743-c986551a68a9/image.png" alt=""></p>
<h1 id="rnns-for-pos-1">RNNs for POS</h1>
<ul>
<li><p>&quot;amazon and spotify&#39;s streaming services are going to devour apple and its music purchasing model
<img src="https://velog.velcdn.com/images/passion_man/post/43d45800-3e26-4637-a9c3-1795442b023a/image.png" alt=""></p>
</li>
<li><p>문장에서 멀리 있는 information 이 효과적으로 전달될 수 있나?</p>
</li>
<li><p>error 가 다시 맨 앞까지 잘 전달될 수 있나?</p>
</li>
<li><p>Recurrent networks are deep in that they involve on layer for each time step -&gt; error 가 모든 곳에 다 전달되어야 한다.</p>
</li>
<li><p>Vanishing gradient problem : as error is back propagated through the layers of a deep netword, they tend toward 0. -&gt; layer가 많고 깊을 수록 error 가 0에 수렴 ( 기울기 소멸 문제 )</p>
</li>
</ul>
<h1 id="long-short---term-memory-network-lstm">Long short - term memory network (LSTM)</h1>
<ul>
<li>RNN 의 변형</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[텍스트 마이닝] 10. Parts Of Speech]]></title>
            <link>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-10.-Parts-Of-Speech</link>
            <guid>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-10.-Parts-Of-Speech</guid>
            <pubDate>Wed, 18 May 2022 04:19:36 GMT</pubDate>
            <description><![CDATA[<h1 id="parts-of-speech">Parts Of Speech</h1>
<ul>
<li>parts of speech are categories of word defined distributionally by the morphological and syntactic contexts  a word appears in. -&gt; POS는 words의 category 분류인데, 형태학적, 문법적인 기준도 기준으로 들어간다.</li>
</ul>
<h2 id="morphological-distribution">Morphological distribution</h2>
<ul>
<li>POS often defiend by distributional properties; verbs = the class of words that each combine with the same set of affixes.
<img src="https://velog.velcdn.com/images/passion_man/post/87ed37dc-13c0-4e48-8e90-e549013f8173/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/c9b11b6c-5fa8-4c78-9937-9faa1ed5b12d/image.png" alt=""></li>
</ul>
<h2 id="syntatic-distribution">Syntatic distribution</h2>
<ul>
<li>Subsitution test : if a word is replaced by another word, does the sentence remain grammatical?
<img src="https://velog.velcdn.com/images/passion_man/post/acd68da8-e4a0-40e2-a198-e4ea8c5df10a/image.png" alt=""></li>
<li>These can often be too strict ; some contexts admit subsitutability for som pairs but not others.</li>
</ul>
<h2 id="pos">POS</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/afe82892-8590-401c-9d2f-9017e0b22bf9/image.png" alt=""></p>
<ul>
<li>OOV -&gt; Out Of Vacabulary , training set 에 존재하지 않는 새로운 단어도 예측</li>
</ul>
<h2 id="pos-tagging">POS tagging</h2>
<p><img src="https://velog.velcdn.com/images/passion_man/post/25149e9a-454d-4d70-883f-97d5459d438d/image.png" alt=""></p>
<ul>
<li>state of the art<ul>
<li>같은 형태여도 news 냐 literature 냐 등의 domain에 따라 달랐다. </li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/7fcfd309-4465-4357-b999-86aa37f2eec9/image.png" alt=""></p>
<h1 id="why-is-pos-tagging-useful">Why is POS tagging useful?</h1>
<ul>
<li>POS indicative of syntax (문법의 척도)
<img src="https://velog.velcdn.com/images/passion_man/post/b01f2e60-51c7-43f9-a6db-06ef4899c759/image.png" alt=""></li>
<li>POS is indicative of pronunciation (발음의 척도) : 예 ; 음성인식 <h1 id="tagsets">Tagsets</h1>
</li>
<li>Penn Treebank</li>
<li>Universal Dependencies</li>
<li>Twitter POS </li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/55c166bd-259a-46d9-ac4c-da48e6e491bc/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/0a898872-998f-44c6-9b49-93ce63910ed4/image.png" alt=""></p>
<ul>
<li>관사 같은 경우에는 Stop words 를 이용해서 관사를 제외하기도 한다. 아무런 의미없이 개수가 많기 때문이다. <h1 id="sequence-labeling">Sequence labeling</h1>
</li>
<li>For a set of inputs x with n sequential time step, one corresponding label y for each x 
  1) 고전적인 방법 : HMM, HEMM, CRF -&gt; 우리는 간단하게 HMM만 알아볼 것 
  2) Neural Network : RNN, LM, Transformer </li>
</ul>
<h2 id="named-entity-recognition">Named entity recognition</h2>
<ul>
<li>wikipedia 에 등장할 만큼 상징적인 것 <blockquote>
</blockquote>
<img src="https://velog.velcdn.com/images/passion_man/post/bc85f0c8-20be-427f-b56c-0fbd173443d5/image.png" alt=""></li>
<li>Named entity 를 하면 apple 이 사과가 아니라 회사라는 걸 알고, 더 많은 정보를 알려줄 수 있으므로 Named entity를 한다. ( Entity Labeling ) </li>
</ul>
<h2 id="hmm">HMM</h2>
<ul>
<li>단순히 확률로만 판단 </li>
<li>Pick the label each word is seen most often with in the training data</li>
</ul>
<h2 id="sequences">Sequences</h2>
<ul>
<li>순서가 있는 데이터에 어떻게 확률분포를 구할 것인가?
<img src="https://velog.velcdn.com/images/passion_man/post/17fcb9ad-64b0-4d9d-8a43-d37488c8c969/image.png" alt=""></li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/13c2dc20-91b5-47bf-87cd-29e56a739b00/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/12830123-4acf-4be9-a4ac-928a5d3b297a/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>[참고]
Generative vs. Discriminative models </p>
<blockquote>
</blockquote>
<ul>
<li>Generative models specify a joint distribution over the labels and the data. With this you could generate new data<blockquote>
</blockquote>
</li>
<li>P( x, y ) = P( y ) P( x | y )<blockquote>
</blockquote>
</li>
<li>Naive Bayes, HMM, GAN 
<img src="https://velog.velcdn.com/images/passion_man/post/086b3859-6efc-426c-8db1-d60bf01e1fbe/image.png" alt=""><blockquote>
</blockquote>
</li>
<li><blockquote>
<p>확률분포를 찾자! </p>
</blockquote>
</li>
<li>Discriminative models specify the conditional distribution of the label y given the data x. These models focus on how to discriminate between the classes.<blockquote>
</blockquote>
</li>
<li>P ( y | x ) <blockquote>
</blockquote>
</li>
<li><blockquote>
<p>logistic regression, RNN, softmax
<img src="https://velog.velcdn.com/images/passion_man/post/c28ea61d-c124-4398-b85c-3263d534190d/image.png" alt=""></p>
</blockquote>
</li>
<li><blockquote>
<p>이진분류 모델을 학습시키자!</p>
</blockquote>
</li>
</ul>
<h2 id="hmm-1">HMM</h2>
<ul>
<li>HMM은 Generative 모델
<img src="https://velog.velcdn.com/images/passion_man/post/67970e2f-fd69-4cb4-90c6-a616bf9d2070/image.png" alt=""></li>
</ul>
<blockquote>
<p>[Hidden Markov Model : HMM의 기본이론]
<img src="https://velog.velcdn.com/images/passion_man/post/51b61449-c03c-4a42-a25c-9946f9aff728/image.png" alt=""></p>
</blockquote>
<ul>
<li>Markov Assumption - 이전 혹은 직전의 Context는 현재를 반영한다. 
<img src="https://velog.velcdn.com/images/passion_man/post/7a7bdd7c-873b-4151-bc88-53c4eaf8271f/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/a264bede-3ed4-41a4-893d-32f3fb4115bc/image.png" alt=""></li>
<li>output Independent - 현재의 y는 x에 영향을 준다. </li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/d5bae300-13de-40f8-8dc6-aabb8e511187/image.png" alt=""></p>
<ul>
<li>P(y)P(x|y) </li>
<li>P(y) : label 끼리의 관계</li>
<li>P(x|y) : 현재 label과 현재 word의 관계 </li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/e6824e48-dcb4-4469-9363-0e631cbd0be5/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/2a6bdd1b-750c-4a52-a7b1-05c881167649/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/4fd0c7b6-3a68-49da-9a5c-43ba6a5c7d95/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/e93dd9d0-dc44-4005-9516-511193977746/image.png" alt=""></p>
<ul>
<li>이미 확률이 다 계산되어 있다. </li>
</ul>
<h2 id="decoding">Decoding</h2>
<ul>
<li>Greedy : proceed left to right, committing to the best tag for each time step (given the sequence seen so far) </li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/0367e77b-a84b-4118-846a-bb70ed833884/image.png" alt=""></p>
<ul>
<li>Information later on in the sentence can influence the best tags earlier on. -&gt; 이미 best 라고 구했던 tag 가 다른 문장 요소에 영향을 줄 수 있다. </li>
<li>Ideally, what we want is to calculate the joint probability of each path and pick the one with the highest probability. But for N time steps and K labels, number of possible paths = KN</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[텍스트 마이닝] 9. Embedding(3)]]></title>
            <link>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-9.-Embedding3</link>
            <guid>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-9.-Embedding3</guid>
            <pubDate>Wed, 18 May 2022 04:00:36 GMT</pubDate>
            <description><![CDATA[<h1 id="elmo">ELMo</h1>
<ul>
<li>Learn parameters to combine the RNN output across all layers for each word in a sentence for a specific task(NER, semantic role labeling, question answering etc.). Large improvements over SOTA(State Of The Arts) for lots of NLP problems.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/96320935-1e40-458f-9f0f-b362e83f6a11/image.png" alt=""></p>
<h1 id="bert">BERT</h1>
<ul>
<li>Learn the parameters of this model with two objectives :
  1) Masked language modeling
  2) Next sentence prediction</li>
</ul>
<p>-Masked LM
    - Masked one word from the input and try to predict that word as the output 
    - More powerful than an RNN LM since it can reason about context on both sides of the word being predicted
    - A BiRNN models context on both sides, but each RNN only has access to information from on direction.</p>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/passion_man/post/8dda550d-444e-4a3a-99bd-f35ce76e9ce1/image.png" alt=""></p>
<ul>
<li>전부 다 masked 하는 건 아니고 한 15% 정도만 하고 예측한다. </li>
</ul>
<blockquote>
</blockquote>
<p>[참고]</p>
<blockquote>
</blockquote>
<ul>
<li>모든 sentence의 첫번째 token은 언제나 [CLS](special classification token) 이다. 이 [CLS] token은 transformer 전체층을 다 거치고 나면 token sequence의 결합된 의미를 가지게 되는데, 여기에 간단한 classifier를 붙이면 단일 문장, 또는 연속된 문장의 classification을 쉽게 할 수 있게 됩니다. 만약 classification task가 아니라면 이 token은 무시하면 됩니다.<blockquote>
</blockquote>
</li>
<li>또한 CLS 로 같은 문서에서 왔는지 다른 문서에서 왔는지를 classification 할 수 있다.</li>
</ul>
<h1 id="next-sentence-prediction">Next sentence prediction</h1>
<ul>
<li>For a pair of sentences, predict from [CLS] representation whether they appeared sequentially in the training data </li>
</ul>
<p><img src="https://velog.velcdn.com/images/passion_man/post/8615abe6-e589-4474-8245-8a00aa4d6e24/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[텍스트 마이닝] 8. Embedding(2)]]></title>
            <link>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-8.-Embedding2</link>
            <guid>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-8.-Embedding2</guid>
            <pubDate>Wed, 18 May 2022 02:46:34 GMT</pubDate>
            <description><![CDATA[<h1 id="word-embedding">Word Embedding</h1>
<ul>
<li>pre-traiend word embeddings great for words that appear frequently in data </li>
<li>Unseen words are treated as UNKs and assigned zero or random vectors; everything unseen is assigned the same representation </li>
</ul>
<blockquote>
</blockquote>
<p>Shared structure</p>
<ul>
<li>Even in languages like English that are not agglutinative and aren&#39;t highly inflected, words share important structure</li>
<li>Even if we never see the word &quot;unfriendly&quot; in our data, we should be able to reason about it as: un + friend + ly</li>
</ul>
<h1 id="subword-model">Subword Model</h1>
<ul>
<li>Rather than learning a single representation for each word type w, learn representation z for the set of ngrams that comprise it -&gt; 분자단위 n-gram으로 쪼개서 학습시킴</li>
</ul>
<h1 id="how-do-we-use-word-embeddings-for-document-classification">How do we use word embeddings for document classification?</h1>
<p><img src="https://velog.velcdn.com/images/passion_man/post/7dc5f87f-ca05-4543-b8d7-9eb2165bdc11/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/c55c806a-ace2-4809-bbd3-0c026dc25bc0/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>[참고]</p>
<blockquote>
</blockquote>
<p>Attention </p>
<blockquote>
</blockquote>
<ul>
<li>weighted sum 을 이용해서 word embeddings 을 사용할 때 사용하는 개념</li>
<li>어떤 단어에 더 집중해야할 지에 따라 비중을 달리한다.</li>
<li>Define v to be a vector to be learned; think of it as an &quot;important word&quot; vector. The dot product here measures how
similar each input vector is to that &quot;important word&quot; vector <blockquote>
</blockquote>
</li>
<li>Lots of variations on attention
  1) Linear transformation of x into before otting with v (선형변환)
  2) Non-linearities after each operation (비선형)
  3) &quot;Multi-head attention&quot; : multiple v vectors to capture different phenomena that can be attended to in the input
  4) Hierarchical attention (sentence representation with attention over words + document representation with attention over sentences  (word 레벨에서 한 번보고 sentence 레벨에서 한 번 보고 ...) <blockquote>
</blockquote>
</li>
<li>Attention gives us a normalized weight  for every token in a sequence that tell us how important that word was for the prediction -&gt; 어떤 단어가 중요했는지 역으로 파악 가능 <ul>
<li>This can be useful for visualization </li>
</ul>
</li>
</ul>
<h1 id="rnn">RNN</h1>
<ul>
<li>With an RNN, we can generate a representation of the sequences as seen through time t. </li>
<li>This encodes a representation of meaning specific to the local context a word is used in. 
<img src="https://velog.velcdn.com/images/passion_man/post/fb1b00b6-e7c0-476e-ab94-a3d52c961b4a/image.png" alt=""></li>
<li>What about the future context? <ul>
<li>RNN 을 이용해서 다음에 나올 단어를 예측해볼 수도 있다.<h1 id="bidirectional-rnn">Bidirectional RNN</h1>
</li>
</ul>
</li>
<li>A powerful alternative is make predictions conditioning both on the past and the future.</li>
<li>Two RNNs
  1) One running left- to- right
  2) Oner right- to- left</li>
<li>The forwadr RNN and backward RNN each output a vector of size H at each time step, which we concatenate into a vector of size 2H. 
<img src="https://velog.velcdn.com/images/passion_man/post/79a4f1fe-20cf-49e4-ba85-ba9cc5ed0b19/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/3b2521dc-bd57-4035-bfb0-ca11e7baebb8/image.png" alt=""></li>
</ul>
<h1 id="stacked-rnn">Stacked RNN</h1>
<ul>
<li>Multiple RNNs, where the output of one layer becomes the input to the next.
<img src="https://velog.velcdn.com/images/passion_man/post/2e4082fa-c476-43fc-a281-382a8cf27d78/image.png" alt=""></li>
</ul>
<h1 id="contextualized-embeddings">Contextualized embeddings</h1>
<ul>
<li>Models for learning static embeddings learn a single representation for a word type -&gt; 지금까지 한 거 </li>
<li>예 : word2vec, glove</li>
<li>단어에 대한 문맥 (순서 X) , 단어자체만 임베딩으로 이용
<img src="https://velog.velcdn.com/images/passion_man/post/847c35f3-9fea-4de9-bb83-f62db15d6d74/image.png" alt=""><ul>
<li>동물 bears, 과일 bears, 야구팀 마스코드 bears 가 모두 같은 벡터로 변환되는 것이 static embedding 이다. </li>
</ul>
</li>
<li>Contextualized word representations </li>
<li>예 : elmo, bert, gpt </li>
<li>단어에 대한 문맥 (순서 O), 언어적 구조, 구조적 특징, domain의 특징 등 학습<ul>
<li>Big idea : transform the representation of a token in a sentence to be sensitive to its local context in a sentence and trainable to be optimized for a specific NLP task</li>
</ul>
</li>
</ul>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/passion_man/post/8c91f206-f634-4044-9fe6-5f9ff175e734/image.png" alt=""></p>
<ul>
<li>BERT는 모든 상관관계를 Attention 을 고려하여 학습 </li>
<li>BERT는 Transformer-besed model 인데 빈칸채우기를 하기위해서 Bidirectional RNN 을 이용하기도 하고 문장을 쪼개서 이어지는 게 말이 맞는지를 확인하기도 한다. </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[텍스트 마이닝] 7. Vector Semantic]]></title>
            <link>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-7.-Vector-Semantic</link>
            <guid>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-7.-Vector-Semantic</guid>
            <pubDate>Wed, 18 May 2022 02:34:51 GMT</pubDate>
            <description><![CDATA[<h1 id="vector-semantics">Vector semantics</h1>
<ul>
<li><p>&quot;You shall know a word by the company it keeps&quot;</p>
<ul>
<li>문맥(context)에 의해서 단어를 파악한다.</li>
</ul>
</li>
<li><p>앞서 봤던 모델들에 넣는 벡터를 어떻게 만드는지 생각해보자</p>
<h1 id="distributed-representation---one---hot-vector">Distributed representation (&lt;-&gt; one - hot vector)</h1>
</li>
<li><p>Vector representation that encodes information about the distribution of context a word appears in</p>
</li>
<li><p>Words that appear in similar contexts have similar representations -&gt; 비슷한 문맥은 비슷한 representation 을 가진다.</p>
</li>
<li><p>We have several different ways we can encode the notion of &quot;context&quot;</p>
<h1 id="term---document-matrix">Term - document matrix</h1>
<p><img src="https://velog.velcdn.com/images/passion_man/post/d5ae885e-7bcf-4a9c-99d4-e5edf208e04a/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/2c1f5496-876a-457f-a3a8-6ef54fce41b7/image.png" alt=""></p>
</li>
</ul>
<h1 id="cosine-similarity">Cosine Similarity</h1>
<p><img src="https://velog.velcdn.com/images/passion_man/post/d58673ba-b145-4c75-a86d-e34ce65b0452/image.png" alt=""></p>
<ul>
<li>We can calculate the cosine silmilarity of two vectors to judge the degree of their similarity</li>
<li>Euclidean distance measures the magnitude of distance between two points</li>
<li>Cosine similarity measures their orientation</li>
<li>Cosine similarity 가 0.7 ~ 0.8 정도면 비슷한 단어라고 할 수 있다.</li>
<li>-1 : 역방향 일치, 0 : 불일치, 1 : 일치<h1 id="tf---idf">TF - IDF</h1>
</li>
<li>Term frequency -inverse document frequency ( TF-IDF )</li>
<li>A scaling to representation a features as function of how frequently it appears in a data point but accounting for its freqency in the overall collection -&gt; 예를 들어, a와 the 같은 관사는 별의미는 없는데 여러 문서에 많이 등장하기는 한다.
<img src="https://velog.velcdn.com/images/passion_man/post/f8232cef-a4ab-4cfa-97fe-3c57d91ff148/image.png" alt=""></li>
</ul>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/passion_man/post/a50cacc3-a9fe-4225-9b3a-83b90429bd7a/image.png" alt=""></p>
<blockquote>
</blockquote>
<ul>
<li>like 는 별의미가 없지만 정보가 없지만 문서에 많이 등장한다. 즉, 특정 문서를 구분할 단서가 되지 않기 때문에 like 에 대한 정보를 떨어트린다. 즉, IDF를 0으로 만들어버린다.</li>
</ul>
<h1 id="intrinsic-evaluation">Intrinsic Evaluation</h1>
<p><img src="https://velog.velcdn.com/images/passion_man/post/122ff6aa-37be-4e08-b252-3d6465d8eba4/image.png" alt=""></p>
<ul>
<li>Relatedness : correlation between vector similarity of pair of words and human judgments -&gt; vector similarity 와 human judgment 두 벡터의 연관성을 분석한다.</li>
<li>Analogical reasoning (Mikolov et al. 2013). For analogy Germany : Berlin :: France : ???, find closest vector to v(&quot;Berlin&quot;) - v(&quot;Germany&quot;) + v(&quot;France&quot;)
<img src="https://velog.velcdn.com/images/passion_man/post/275c0577-6a9a-4610-aa06-416d28fd42ed/image.png" alt=""></li>
</ul>
<h1 id="sparse-vectors---dense-vectors-word-embedding">Sparse vectors -&gt; Dense vectors (Word embedding)</h1>
<ul>
<li>Learning low-dimensional(약 50~300차원) representations of words by framing a predicting task : using context to predict words in a surrounding window</li>
<li>Transform this into a supervised prediction problem; similar to language modeling but we&#39;re ignoring order whitin the context window</li>
</ul>
<p>Dense vectors from prediction</p>
<ul>
<li>skipgram model(Mikolov et al. 2013) : give a single word in a sentence, predict the words in a context window around it.<ul>
<li>먼저 임의의 값으로 벡터들을 초기화한 후, 특정 단어가 주어졌을 때 그 주변 단어들의 등장 확률을 증가시키는 방향으로 학습하는 알고리즘이다. 가량 I love him but he hates me. 라는 문장을 생각해보자. 여기서 him 이라는 단어를 기준으로 앞 뒤 두 단어들인 I, love, but, he의 발생 확률을 증가시키는 방향으로 학습하게 된다. ( 여기서 앞 뒤 두 단어라고 했으니 window size = 2 이다. )</li>
</ul>
</li>
</ul>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/passion_man/post/d7bd324a-49a1-41c5-b86c-6005d5fef3a9/image.png" alt=""></p>
<ul>
<li><p>비슷한 문맥에서 등장하는 context -&gt; skip-gram 등의 방법으로 word embedding 을 만든다. -&gt; 비슷한 context 는 비슷한 vector 값을 가지게 된다.</p>
</li>
<li><p>Mikolov et al. 2013 show that vector representations have some potential for analogical reasoning through vector arithmetic ( = Analogical inference = analogy reasoning )
<img src="https://velog.velcdn.com/images/passion_man/post/997775e6-d1ec-49bb-801a-d1c51991d304/image.png" alt=""></p>
</li>
</ul>
<blockquote>
</blockquote>
<p>Low - dimensional distributed representation</p>
<blockquote>
</blockquote>
<ul>
<li>Low-dimensional, dense word representations are extradrdinarily powerful</li>
<li>Lets your representation of the input share statistical strength with words that behave similarly in terms of their sidtributional properties (often synonyms or words that belong to the same class)<blockquote>
</blockquote>
Two kinds of training data</li>
<li>The labeled data for a specific task (e.g., labeled sentiment for movie reviews) : 2K labels/reviews, ~ 1.5M words-&gt; used to train a supervised model</li>
<li>General text ( Wikipedia, the web, books, etc .), -&gt; ~trillions of words -&gt; used train word distributed representation<blockquote>
</blockquote>
using dense vectors</li>
<li>In neural models (CNNs, RNNs, LM), replace the V-demensional sparse vector with the much smaller K-dimensional dense one.</li>
<li>Can alse take the derivative of the loss function with respect to those representations to optimize for a paricular task. -&gt; dense vector로 특정 task 를 최적화하기 위해서 손실함수를 미분할 수도 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[텍스트 마이닝] 6. Language Model(2)]]></title>
            <link>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-6.-Language-Model2</link>
            <guid>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-6.-Language-Model2</guid>
            <pubDate>Wed, 18 May 2022 02:18:39 GMT</pubDate>
            <description><![CDATA[<h1 id="logistic-regression--classification">Logistic regression : Classification</h1>
<ul>
<li>LM : We can use multiclass logistic regression for language modeling by treating the vocabulary as the output space <h1 id="여러-가지-lm-모델들">여러 가지 LM 모델들</h1>
<img src="https://velog.velcdn.com/images/passion_man/post/9e4725a8-6024-450b-89cc-c104d9900a2a/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/8e06782a-117f-4abf-9cc9-ccdb2c41cb36/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/0e562618-02f7-4ac6-8fb9-1337d3bded01/image.png" alt=""></li>
</ul>
<blockquote>
</blockquote>
<p>[참고]
Richer representations</p>
<blockquote>
</blockquote>
<ul>
<li>Log-linear models give us the flexibility of encoding richer representations of the context we are conditioning on.</li>
<li>We can reason about any observations from the entire history and not just the local context</li>
</ul>
<h1 id="neural-lm--classification">Neural LM : Classification</h1>
<ul>
<li>input x = vector concatenation of a conditioning context of fixed size k
<img src="https://velog.velcdn.com/images/passion_man/post/7ad1ea46-0f68-40be-bc45-f767d2ad7b1d/image.png" alt=""></li>
<li>단어 vector 를 이어붙여서 x input을 만들 수 있다.
<img src="https://velog.velcdn.com/images/passion_man/post/dfaf1e67-d201-4737-a52a-6123eaf14eac/image.png" alt=""></li>
<li>softmax : multi classification 할 때 사용하고, 모든 y개 class 확률분포의 합이 1이 되는 함수이다. 
<img src="https://velog.velcdn.com/images/passion_man/post/b399438b-3f11-464d-838b-ac7e3ed7d808/image.png" alt=""></li>
</ul>
<h1 id="recurrent-neural-network-rnn--classification">Recurrent neural network (RNN) : Classification</h1>
<p><img src="https://velog.velcdn.com/images/passion_man/post/7903b5c1-efd4-4057-ae7d-a249a62a5427/image.png" alt=""></p>
<ul>
<li>Sequential data 이용할 때, RNN 주로 사용</li>
<li>RNN 은 순서의 특징을 잘 잡아낸다.</li>
<li>이전 history 를 중요도에 따라 차등 적용한다.</li>
<li>각 state 마다 output 출력이 가능하다. -&gt; 번역에 사용 가능</li>
<li>RNN은 bigram, trigram, ... 을 넘어서 x1이 x5에 영향을 더 많이 준다면 x1의 β 값을 높인다. 
<img src="https://velog.velcdn.com/images/passion_man/post/dcafc584-66ca-44f0-be54-bcf979b6e805/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/e4c702ee-5083-4ad0-9819-6d44cf6fd3ca/image.png" alt=""></li>
<li>s1은 이전까지의 상태의 정보를 다 담아둔 학습 벡터 -&gt; 중요한 정보는 많이 기억하고, 관사 같이 덜 중요한 건 덜 담는다. </li>
<li>s1 : Current state</li>
<li>s0 : Previous state</li>
<li>x1 : Current input
<img src="https://velog.velcdn.com/images/passion_man/post/ec0a2e7f-df92-4ccc-9c8f-2be0f990759e/image.png" alt=""></li>
<li>g = tanh or relu / O = softmax</li>
</ul>
<h1 id="training-rnns">Training RNNs</h1>
<p><img src="https://velog.velcdn.com/images/passion_man/post/01d8f932-b526-4a05-ab95-766068c20c26/image.png" alt=""></p>
<ul>
<li>Back Propaganda 를 통해서 학습한다.
<img src="https://velog.velcdn.com/images/passion_man/post/7f71078c-f009-4029-9111-5a07986bd6a6/image.png" alt=""></li>
<li>True y와 y햇의 loss 를 매 step마다 loss가 작아지는 방향으로 update한다. 
<img src="https://velog.velcdn.com/images/passion_man/post/3c7ff7ca-d8a6-48d1-9bfd-0edaa40320cf/image.png" alt=""></li>
<li>Current input 을 변형시켜서 넣어줄 수도 있다. <h1 id="rnn--generation---rnn-이-generation-모델로도-사용될-수-있다">RNN : Generation -&gt; RNN 이 Generation 모델로도 사용될 수 있다.</h1>
<img src="https://velog.velcdn.com/images/passion_man/post/4c385aba-2b7e-4708-a24a-00e279d7da1c/image.png" alt=""></li>
<li>RNN은 각각의 state마다 output 을 알 수 있으니까 이 output을 위의 그림과 같이 활용하면 Generation의 방법으로 사용할 수 있다. </li>
</ul>
<p>출처 : <a href="https://people.ischool.berkeley.edu/~dbamman/nlp21.html">https://people.ischool.berkeley.edu/~dbamman/nlp21.html</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[텍스트 마이닝] 5. Language Model(1)]]></title>
            <link>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-5.-Language-Model1</link>
            <guid>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-5.-Language-Model1</guid>
            <pubDate>Wed, 18 May 2022 02:06:13 GMT</pubDate>
            <description><![CDATA[<h1 id="language-model">Language Model</h1>
<ul>
<li><p>Language models provide us with a way to quantify the likelihood fo a sequence -- i.e., plausible sentences. -&gt; 말이 되면 확률값이 높다. </p>
</li>
<li><p>P(&quot;Call me Ishmael&quot;) = P(w1 = &quot;call&quot;, w2 = &quot;me&quot;, w3 = &quot;Ishmael&quot;) X P(STOP) -&gt; v+ is the infinite set of sequences of symbols from v; each sequence ends with STOP</p>
</li>
<li><p>Language modeling is the task of estimating P(w)</p>
</li>
<li><p>예시
  1) OCR : Image to Text ( Optical character recognition )
  2) Machine translation -&gt; 1. 원본의 문장을 얼마나 추실하게 전달했느냐(충실도, Fidelity to source text) 와 2.번역된 게 얼마나 정확하냐(Fluency of the translation) 를 본다. 
  3) Query auto completion : 검색어 자동완성 ( 확률이 높은 순서대로 나열 )
  4) Speech recognition -&gt; 시리, 빅스비, 아리아, 알렉사, ... </p>
</li>
</ul>
<h1 id="markov-assumption--estimation">Markov assumption : Estimation</h1>
<ul>
<li>현재 혹은 다음에 올 상태는 이전의 상태(단어)들에 의해 결정된다.
<img src="https://velog.velcdn.com/images/passion_man/post/696c2fff-8469-4a8c-bfc3-32826c08ec06/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/da3feae8-708a-4d36-a977-a9e924c8dd54/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/cdf1a560-8d45-43fd-845b-32c1dee11c28/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/5ef9a25e-bede-40ae-aa7a-a432e9a9808a/image.png" alt=""></li>
</ul>
<h1 id="markov-assumption--generating">Markov assumption : Generating</h1>
<ul>
<li>어떤 단어 다음에 특정 단어가 나올 확률을 Language model을 통해서 미리 계산해서 둔다. </li>
<li>What we learn in estimating languege models is P(word | context), where context -- at least here -- is the previous n-1 words </li>
<li>We have one multinomial over the vocabulary (including STOP) for each context </li>
<li>LM 또한 확률분포를 다루기 때문에 확률분포 값이 0이 되는 곳이 있다면 전체 확률이 0이 된다. 따라서 Smoothing 을 통해서 해결한다. -&gt; How can best re-allocate probability mass가 또 하나의 이슈이다. </li>
</ul>
<h1 id="interpolation">Interpolation</h1>
<ul>
<li>As ngram order rises, we have the potential for higher precision but also higher variablilty in our estimates. -&gt; ngram에서 n이 커질 수록 정확도가 커지지만 다양성이 늘어난다. </li>
<li>A linear interpolation of any two language models p and q is also a valid language model -&gt; 여러 모델을 비중을 다르게 하여 동시에 사용할 수도 있다. (예1. p= bigram, q= trigram / 예2. p = the web, q = pollitical speeches) .. 
<img src="https://velog.velcdn.com/images/passion_man/post/51188a3c-9c9d-4d4d-bb3e-c66d75f427c7/image.png" alt=""></li>
<li>꼭 2개가 아니고 더 많은 개수를 같이 쓸 수도 있다.
<img src="https://velog.velcdn.com/images/passion_man/post/b1d2ea5d-dca7-4b82-b22b-186f8142950f/image.png" alt=""><ul>
<li>how do we pick the best values of λ? : λ -&gt; 사람이 개입해서 바꿀 수 있다. hyper parameter 
1) Grid search over development corpus
2) Expectation-Maximization algorithm </li>
</ul>
</li>
</ul>
<h1 id="여러-가지-lm-모델들">여러 가지 LM 모델들</h1>
<ul>
<li>Unigram, bigram, trigram, 4gram model, ..</li>
</ul>
<h1 id="evaluation">Evaluation</h1>
<ul>
<li>The best evaluation metrics are external - how does a better language model influence the application you care about? -&gt; 외부의 특정 조건 (Accuracy, Precision, ... 등등 외부 지표가 좋다)</li>
<li>Speech recognition (word error rate), machine translation (BLEU score) topic models (sensemaking) -&gt; BLEU 스코어 : 번역이 잘 되었는지 평가하는 외부 지표</li>
<li>A good language model should judge unseen real language to have high probability</li>
<li>Perplexity = inverse probability of test data, averaged by word</li>
<li>To be reliable, the test data must be truly unseen</li>
</ul>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/passion_man/post/e24f97ec-808d-4d42-a250-24d7ee53ff3f/image.png" alt="">
-&gt; Perplexity 는 외부 지표가 없을 때 사용할 수 있는 지표인데, test set으로 검증했을 때 확률이 높아야 한다. 꼭 test set 으로 검증해야 한다. </p>
<ul>
<li>perplexity 는 Generation의 성능을 판단하는 지표로 낮을 수록 좋다. </li>
<li>ngram에서 n이 커질 수록 perplexity 가 낮아진다.</li>
</ul>
<p>출처 : <a href="https://people.ischool.berkeley.edu/~dbamman/nlp21.html">https://people.ischool.berkeley.edu/~dbamman/nlp21.html</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[텍스트 마이닝] 4. Classification - Neural Network]]></title>
            <link>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-4.-Classification-Neural-Network</link>
            <guid>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-4.-Classification-Neural-Network</guid>
            <pubDate>Wed, 18 May 2022 02:00:30 GMT</pubDate>
            <description><![CDATA[<h1 id="neural-networks">Neural Networks</h1>
<p><img src="https://velog.velcdn.com/images/passion_man/post/3096b6ec-059b-4fdc-8d16-e6620ce8cb5d/image.png" alt="">
<img src="https://velog.velcdn.com/images/passion_man/post/63ba0479-5273-4b2d-a95d-e264599d683d/image.png" alt=""></p>
<ul>
<li>Prediction 과 Backpropagation 의 반복이다. 처음에 Weight 값을 임의의 값으로 설정하고 y-y햇이 최소화되게끔 업데이트한다. </li>
</ul>
<blockquote>
</blockquote>
<p>[참고]</p>
<ul>
<li>Discrete, high-dimensional representation of inputs (one-hot vectors, indicator vector) -&gt; low-dimensional distributed representation </li>
<li>Static representation -&gt; contextual representations, where representations of words are sensitive to local context</li>
<li>Non-linear interactions of input features</li>
<li>Multiple layers to capture hierarchical structure </li>
</ul>
<blockquote>
</blockquote>
<p>[참고]
Activation function : 앞에서 주어진 신호를 다음 레이어로 보낼지 말지 결정
<img src="https://velog.velcdn.com/images/passion_man/post/d5719762-5ad2-4ac5-878b-483481b43324/image.png" alt=""></p>
<ul>
<li>y-y햇 즉, 오차를 줄여나가는 과정에서 기울기 소멸 문제가 발생한다. 이 때 LeLU 함수를 활성화 함수로 사용하면 기울기 소멸 염려도 없다. 또한 가장 대중적이고 속도가 빠르다. </li>
<li>ReLU and tanh are both used extensively in modern system.</li>
<li>Sigmoid is useful for final layer to scale output between 0 and 1, but is not often used in intermediate layers</li>
</ul>
<h1 id="neural-networks-의-장점">Neural Networks 의 장점</h1>
<ul>
<li><p>Tremendous flexibility on design choices (exchange feature engineering for model engineering) -&gt; Model을 바꾸기 쉽다. </p>
</li>
<li><p>Articulate model structure and use the chain rule to derive parameter updates</p>
<h1 id="문제점">문제점</h1>
</li>
<li><p>컴퓨터로 무한정 노드를 늘릴 수가 있다. 하지만 쓸 데 없고 상대적으로 덜 중요한 곳에 계산을 사용하지말고 필요한 x에  β를 잘 (적당히) 할당할 수 있게 해야한다. </p>
</li>
<li><p>Regularization : Increasing the number of parameters = Increasing the possibility for overfitting to training data -&gt; 과대적합을 막기 위해서 규제를 한다. 
  1) L2 Regularization
  2) Dropout : When training on a &lt;x,y&gt; pair, randomly remove some node and weights
  3) Early stopping : Stop backpropagation before the training error is too small</p>
<p>  <img src="https://velog.velcdn.com/images/passion_man/post/74634cc5-e35c-48f2-bdae-357d4517f7d9/image.png" alt=""></p>
</li>
</ul>
<h1 id="neural-networks-를-이용한-여러-가지-h를-학습시키는-방법--classification">Neural Networks 를 이용한 여러 가지 h를 학습시키는 방법 : Classification</h1>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/passion_man/post/31924691-701e-4d77-a60c-c5b801076a76/image.png" alt=""></p>
<ul>
<li>다 계산하면 복잡하니까 hidden-layer의 큰 값만 뽑아내서 진행</li>
</ul>
<blockquote>
<p><img src="https://velog.velcdn.com/images/passion_man/post/bfa1a8f9-2740-4a04-b68a-f7e389a35a55/image.png" alt=""></p>
</blockquote>
<ul>
<li>모든 hidden layer에서 가장 큰 값으로 진행</li>
</ul>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/passion_man/post/b5df245c-735a-43f2-bad0-41dc65d3e2e6/image.png" alt=""></p>
<ul>
<li>CNN<ul>
<li>We can specify multiple filters; each filter is a separate set of parameters to be learned</li>
<li>With max pooling, we select a single number for each filter over all tokens </li>
<li>If we specity multiple filters, we can also scope each filter over different window sizes</li>
</ul>
</li>
</ul>
<p>출처 : <a href="https://people.ischool.berkeley.edu/~dbamman/nlp21.html">https://people.ischool.berkeley.edu/~dbamman/nlp21.html</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[텍스트 마이닝] 3. Classification  - Logistic Regression ]]></title>
            <link>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-3.-Classification-Logistic-Regression</link>
            <guid>https://velog.io/@passion_man/%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%A7%88%EC%9D%B4%EB%8B%9D-3.-Classification-Logistic-Regression</guid>
            <pubDate>Wed, 18 May 2022 01:53:08 GMT</pubDate>
            <description><![CDATA[<h1 id="logistic-regression-모델로-h를-학습시키는-방법--classification">Logistic regression 모델로 h를 학습시키는 방법 : Classification</h1>
<p><img src="https://velog.velcdn.com/images/passion_man/post/cef59f04-a937-49b0-bec6-b6e97d87e28f/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/passion_man/post/55323498-ed4a-44dd-8171-d8b178cf9ae6/image.png" alt=""></p>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/passion_man/post/4b73434c-c291-4180-95c2-5eb8faf62bd8/image.png" alt=""></p>
<ul>
<li>확률이 0이 되는 것을 막기 위해서 BIAS를 주고 이런 방식으로 h햇을 학습시킨다. </li>
</ul>
<blockquote>
</blockquote>
<p>[참고]
<img src="https://velog.velcdn.com/images/passion_man/post/10595286-4e16-4fe8-ac2c-456a89b57d5e/image.png" alt=""></p>
<ul>
<li><p>Features</p>
<ul>
<li>As a discriminative classifier, logistic regression doesn&#39;t assum features are independent like Naive Bayes does. -&gt; 독립X</li>
<li>Its power partly comes in the ability to create richly expressive features without the burden of independence.</li>
<li>We can represent text through features that are not just identities of individual words, but any feature that is scopred over the entirety of the input </li>
<li>Features are where you can encode your won domain understanding of the problem. ( unigram, bigram .. ngram, prexies(words that start with &quot;un-&quot;, has word that shows up in positive sentiment dictionary)<ul>
<li>단어의 단순한 유무 말고, input에 대한 정보 추가가 가능하다. </li>
</ul>
</li>
</ul>
<blockquote>
</blockquote>
<p>[참고]
Conditional likelihood 
<img src="https://velog.velcdn.com/images/passion_man/post/a0fec4f0-c7c7-4300-9c83-dfc7bb007e42/image.png" alt=""></p>
</li>
<li><p>For all training data, we want the probability of the true label y for each data point x to be high 
<img src="https://velog.velcdn.com/images/passion_man/post/55991939-150e-4822-8d6b-f6ed946df9eb/image.png" alt=""></p>
</li>
<li><p>This principle gives us a way to pick the values of the parameters β that maximize the probability of the training data
&lt;x,y&gt; -&gt; y를 잘 근사하기 위한 파라미터 β를 잘 설정해야 한다. </p>
</li>
</ul>
<blockquote>
</blockquote>
<p>[참고]
β</p>
<ul>
<li>The value β of that maximizes likelihood also maximizes the log likelihood (최대우도법)
<img src="https://velog.velcdn.com/images/passion_man/post/e12f9f25-49fa-476a-83f1-6deca99902b5/image.png" alt=""></li>
<li>log 를 사용하면 확률값을 다룰 때 더 용이하다. </li>
<li>이렇게 β 값을 최적화 하는 과정에서 기울기 감소 문제가 발생할 수 있다. -&gt; lr 을 잘 조정해서 극복할 수 있다. </li>
</ul>
<h1 id="문제점">문제점</h1>
<ul>
<li>β 값을 최적화 하는 과정에서 기울기 감소 문제<ul>
<li>Calculate the derivative of some loss function with respect to parameters we can change, update accordingly to make predictions on training data a little less wrong next time.</li>
</ul>
</li>
</ul>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/passion_man/post/bcd77865-e3d8-4b85-8ed5-470c6660cccd/image.png" alt=""> </p>
<ul>
<li>상대적으로 그다지 중요하지 않은 feature 들이 영향을 크게 줄 수도 있다. </li>
</ul>
<h1 id="문제-해결">문제 해결</h1>
<ul>
<li>We could threshold features by minimun count but that also throws away information</li>
<li>We can take a probabilistic approach and encode a prior belief that all β should be 0 unless we have strong evidence otherwise</li>
<li>포괄적으로 문장을 설명할 수 있도록 한다. (너무 자세하지 않게)</li>
<li>L2 regularization -&gt; feature 복잡도를 낮춘다.
<img src="https://velog.velcdn.com/images/passion_man/post/edaa2660-e57d-42d2-9a6c-242933106405/image.png" alt=""></li>
<li>L1 regularization -&gt; 필요없는 feature 는 0으로 바꿔버린다.
<img src="https://velog.velcdn.com/images/passion_man/post/97bff96c-4060-4696-98a2-7af3c6582935/image.png" alt=""></li>
</ul>
<p>출처 : <a href="https://people.ischool.berkeley.edu/~dbamman/nlp21.html">https://people.ischool.berkeley.edu/~dbamman/nlp21.html</a></p>
]]></description>
        </item>
    </channel>
</rss>