<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.8.5">Jekyll</generator><link href="keithlee94.github.io/KeithLog/feed.xml" rel="self" type="application/atom+xml" /><link href="keithlee94.github.io/KeithLog/" rel="alternate" type="text/html" /><updated>2019-05-27T08:57:44+00:00</updated><id>keithlee94.github.io/KeithLog/feed.xml</id><title type="html">KeithLog</title><subtitle>SSAFY 교육내용, 알고리즘 문제풀이 정리하여 업로드할 블로그</subtitle><author><name>Jaehyun Keith Lee</name><email>wogus4187@naver.com</email></author><entry><title type="html">Os_deadlock</title><link href="keithlee94.github.io/KeithLog/os/OS_Deadlock/" rel="alternate" type="text/html" title="Os_deadlock" /><published>2019-04-22T00:00:00+00:00</published><updated>2019-04-22T00:00:00+00:00</updated><id>keithlee94.github.io/KeithLog/os/OS_Deadlock</id><content type="html" xml:base="keithlee94.github.io/KeithLog/os/OS_Deadlock/">&lt;h1 id=&quot;deadlock-발생조건&quot;&gt;Deadlock 발생조건&lt;/h1&gt;
&lt;ol&gt;
  &lt;li&gt;Mutual Exclusion&lt;/li&gt;
  &lt;li&gt;Hold and Wait&lt;/li&gt;
  &lt;li&gt;No Preemption&lt;/li&gt;
  &lt;li&gt;Circular Wait
    &lt;ul&gt;
      &lt;li&gt;위 4가지 조건을 동시에 만족할 경우 deadlock 발생 가능&lt;/li&gt;
      &lt;li&gt;예
 &lt;img src=&quot;https://user-images.githubusercontent.com/23356503/56508395-192a1e80-655f-11e9-9dd3-4a21bc005c0f.png&quot; alt=&quot;Deadlock1&quot; /&gt;
 &lt;img src=&quot;https://user-images.githubusercontent.com/23356503/56508415-2a732b00-655f-11e9-8d74-0aa831b42c42.png&quot; alt=&quot;Deadlock2&quot; /&gt;&lt;/li&gt;
    &lt;/ul&gt;
    &lt;ul&gt;
      &lt;li&gt;그래프에 cycle이 없다: Deadlock이 발생하지 않는다&lt;/li&gt;
      &lt;li&gt;그래프에 cycle이 있다
        &lt;ul&gt;
          &lt;li&gt;각 자원이 단 1개의 instance로 구성되어 있다: deadlock 확실&lt;/li&gt;
          &lt;li&gt;여러개의 instance로 구성되어 있다: deadlock 발생 가능성 있음&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;deadlock-prevention&quot;&gt;Deadlock Prevention&lt;/h1&gt;
&lt;ol&gt;
  &lt;li&gt;Mutual Exclusion
    &lt;ul&gt;
      &lt;li&gt;프로세스들간에 공유되지 않는 자원에 대해서만 mutual exclusion 설정&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Hold and Wait
    &lt;ul&gt;
      &lt;li&gt;프로세스 실행 전 프로세스 수행에 필요한 모든 자원을 할당한다
        &lt;ul&gt;
          &lt;li&gt;low resource utilization  - starvation 가능성&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;No Preemption
    &lt;ul&gt;
      &lt;li&gt;프로세스 실행에 필요한 모든 자원이 없다면 현재 이 프로세스에 할당된 자원 모두 반환&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Circular Wait
    &lt;ul&gt;
      &lt;li&gt;각 resource에 번호를 매겨 번호순으로 자원을 요청하도록 한다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;deadlock-avoidence&quot;&gt;Deadlock Avoidence&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;각각의 프로세스가 최대 몇개의 자원을 필요로 하는지 알아야 한다&lt;/li&gt;
  &lt;li&gt;Safe State: 프로세스에서 요청한 자원 할당시 시스템의 상태가 안전 상태인지 호가인해야 한다
    &lt;ul&gt;
      &lt;li&gt;Deadlock이 없는 상태&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;Resouce Allocation Graph
    &lt;ul&gt;
      &lt;li&gt;각 프로세스에 대한 자원 요청 그래프를 그린 후 자원 할당시 그래프에 cycle이 발생하면 deadlock이 발생 가능함을 의미하므로 할당하지 않는다.&lt;/li&gt;
      &lt;li&gt;예
  &lt;img src=&quot;https://user-images.githubusercontent.com/23356503/56508888-76729f80-6560-11e9-9cec-c4842e457d6c.png&quot; alt=&quot;Resource Allocation Graph&quot; /&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Banker’s Algorithm
    &lt;ul&gt;
      &lt;li&gt;프로세스가 자원 요청시 우선 대기시킨다&lt;/li&gt;
      &lt;li&gt;프로세스에게 자원 할당시 반드시 유한한 시간 내에 반납되어야 한다&lt;/li&gt;
      &lt;li&gt;instances
        &lt;ul&gt;
          &lt;li&gt;n: 프로세스 갯수, m: 자원 type 수&lt;/li&gt;
          &lt;li&gt;Available
            &lt;ul&gt;
              &lt;li&gt;길이 m인 vector&lt;/li&gt;
              &lt;li&gt;available[j] = k: R(j)는 k개의 instance 보유중&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;Max
            &lt;ul&gt;
              &lt;li&gt;n * m matrix&lt;/li&gt;
              &lt;li&gt;Max[i, j] = k: P(i) 수행에 R(j)가 k개 필요&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;Allocation
            &lt;ul&gt;
              &lt;li&gt;n * m matrix&lt;/li&gt;
              &lt;li&gt;Allocation[i, j] = k: P(i)에 현재 R(j)가 k만큼 할당됨&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;Need
            &lt;ul&gt;
              &lt;li&gt;n * m matrix&lt;/li&gt;
              &lt;li&gt;Need[i, j] = k: P(i)에 R(j)가 k개 더 필요하다&lt;/li&gt;
              &lt;li&gt;Need[i, j] = Max[i, j] - Allocation[i, j]&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Safety Algorithm&lt;/p&gt;

        &lt;ol&gt;
          &lt;li&gt;

            &lt;ul&gt;
              &lt;li&gt;Work: 길이 m인 vector. Work = Available로 초기화&lt;/li&gt;
              &lt;li&gt;Finish: 길이 n인 vector. 전부 false로 초기화&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;

            &lt;ul&gt;
              &lt;li&gt;모든 j에 대해 Finish[i] = false &amp;amp;&amp;amp; Need[i, j] &amp;lt;= Work[i] 인 i를 찾는다.&lt;/li&gt;
              &lt;li&gt;있으면 3으로, 없으면 4로 이동&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;

            &lt;ul&gt;
              &lt;li&gt;Work[i] = Work[i] + Allocation[i]&lt;/li&gt;
              &lt;li&gt;Finish[i] = true&lt;/li&gt;
              &lt;li&gt;2로 이동&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;

            &lt;ul&gt;
              &lt;li&gt;Finish[i]가 전부 true이면 시스템은 안전 상태이다&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Resouce Request Algorithm&lt;/p&gt;

        &lt;ol&gt;
          &lt;li&gt;

            &lt;ul&gt;
              &lt;li&gt;Request: P(i)의 request vector&lt;/li&gt;
              &lt;li&gt;Request[i, j]: P(i)가 R(j)를 k개 요청한다&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;

            &lt;ul&gt;
              &lt;li&gt;Request[i, j] &amp;lt;= Need[i, j]면 3으로 이동&lt;/li&gt;
              &lt;li&gt;Request[i, j] &amp;gt; Need[i, j]: 필요 자원 이상을 요청하는 경우이므로 에러&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;

            &lt;ul&gt;
              &lt;li&gt;Available[j] = Available[j] - Request[i, j]&lt;/li&gt;
              &lt;li&gt;Allocation[i, j] = Allocation[i, j] + Request[i, j]&lt;/li&gt;
              &lt;li&gt;Need[i, j] = Need[i, j] - Request[i, j]&lt;/li&gt;
              &lt;li&gt;계산 결과 safe상태면 P(i)에 k만큼 R(j) 할당, 아니면 자원 할당하지 않음&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Deadlock Detection&lt;/p&gt;

        &lt;ol&gt;
          &lt;li&gt;

            &lt;ul&gt;
              &lt;li&gt;Work: Work = Available로 초기화&lt;/li&gt;
              &lt;li&gt;Finish: 모든 j에 대해 Allocation[i, j]가 0이면 true, 아니면 false&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;

            &lt;ul&gt;
              &lt;li&gt;Finish[i] = false &amp;amp;&amp;amp; Request[i, j] &amp;lt;= Work[i, j]인 i를 찾는다.&lt;/li&gt;
              &lt;li&gt;있으면 3, 없으면 4로 이동&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;

            &lt;ul&gt;
              &lt;li&gt;Work[i, j] = Work[i, j] + Allocation[i, j]&lt;/li&gt;
              &lt;li&gt;Finish[i] = true&lt;/li&gt;
              &lt;li&gt;2로 이동&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;

            &lt;ul&gt;
              &lt;li&gt;Finish[i] 가 false인 것이 있으면 deadlock 상태&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ol&gt;

        &lt;ul&gt;
          &lt;li&gt;O(m * n^2)의 시간복잡도&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;recovery-from-deadlock&quot;&gt;Recovery from Deadlock&lt;/h1&gt;
&lt;ol&gt;
  &lt;li&gt;Process Termination
    &lt;ul&gt;
      &lt;li&gt;deadlock과 연관된 모든 프로세스들을 deadlock이 사라질때까지 1개씩 종료&lt;/li&gt;
      &lt;li&gt;고르는 기준
        &lt;ol&gt;
          &lt;li&gt;프로세스 우선순위&lt;/li&gt;
          &lt;li&gt;프로세스가 얼마나 오래 실행되었고 얼마나 더 실행되어야 하는지&lt;/li&gt;
          &lt;li&gt;프로세스가 자원을 얼마나 사용중인지&lt;/li&gt;
          &lt;li&gt;프로세스가 완료되려면 자원이 얼마나 더 필요한지&lt;/li&gt;
          &lt;li&gt;몇개의 프로세스가 종료되어야 하는지&lt;/li&gt;
          &lt;li&gt;프로세스가 interactive 프로세스인지 batch 프로세스인지&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Resouce Preemption
    &lt;ul&gt;
      &lt;li&gt;자원을 뺏을 프로세스 선택 - 손실이 적은 방향으로&lt;/li&gt;
      &lt;li&gt;프로세스 복구, 재시작&lt;/li&gt;
      &lt;li&gt;Starvation 발생 가능&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;</content><author><name>Jaehyun Keith Lee</name><email>wogus4187@naver.com</email></author><category term="Synchronization" /><summary type="html">Deadlock 발생조건 Mutual Exclusion Hold and Wait No Preemption Circular Wait 위 4가지 조건을 동시에 만족할 경우 deadlock 발생 가능 예 그래프에 cycle이 없다: Deadlock이 발생하지 않는다 그래프에 cycle이 있다 각 자원이 단 1개의 instance로 구성되어 있다: deadlock 확실 여러개의 instance로 구성되어 있다: deadlock 발생 가능성 있음</summary></entry><entry><title type="html">Os_process_synchronization</title><link href="keithlee94.github.io/KeithLog/os/OS_Process_Synchronization/" rel="alternate" type="text/html" title="Os_process_synchronization" /><published>2019-04-22T00:00:00+00:00</published><updated>2019-04-22T00:00:00+00:00</updated><id>keithlee94.github.io/KeithLog/os/OS_Process_Synchronization</id><content type="html" xml:base="keithlee94.github.io/KeithLog/os/OS_Process_Synchronization/">&lt;h1 id=&quot;process-synchronization&quot;&gt;Process Synchronization&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;필요성: 여러 프로세스 동시 실행시 공유되는 데이터의 일관성이 깨질 수 있다
    &lt;ul&gt;
      &lt;li&gt;race condition: 데이터에 어떤 프로세스가 먼저 접근하는지에 따라 결과가 달라지는 경우&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;critical-section&quot;&gt;Critical Section&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;공유 자원에 접근하는 코드의 일부.&lt;/li&gt;
  &lt;li&gt;모든 프로세스는 각자의 critical section을 갖는다.&lt;/li&gt;
  &lt;li&gt;한 프로세스가 critical section에 진입했을 경우 다른 프로세스들은 진입할 수 없어야 한다.&lt;/li&gt;
  &lt;li&gt;구조
    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  do{
      entry section
      critical section
      exit section
      remainder section
  } while(true);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;solution-for-critical-section-problem&quot;&gt;Solution for Critical Section Problem&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Mutual Exclusion
    &lt;ul&gt;
      &lt;li&gt;어떤 프로세스가 critical section 내에 있을 경우 다른 프로세스는 critical section 진입 불가&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Progress
    &lt;ul&gt;
      &lt;li&gt;critical section 내에 어떠한 프로세스도 없고 critical section에 진입하고자 하는 프로세스가 있을 경우 이 프로세스는 반드시 critical section에 진입할 수 있어야 한다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Bounded Waiting
    &lt;ul&gt;
      &lt;li&gt;critical section 진입을 요청한 프로세스는 유한한 시간 내에 critical section에 진입해야 한다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Locking
    &lt;ul&gt;
      &lt;li&gt;critical section을 locking으로 보호한다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;mutex-locks&quot;&gt;Mutex Locks&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;acquire(): locking 설정. critical section 접근 권한을 얻는다&lt;/li&gt;
  &lt;li&gt;release(): locking 해제. critical section에서 나갈때 실행한다&lt;/li&gt;
  &lt;li&gt;acquire, release 연산은 atomic해야 한다: 두 연산이 동시에 일어날 수 없다&lt;/li&gt;
  &lt;li&gt;busy waiting: 다른 프로세스가 lock을 가지고 있으면 lock을 걸고자 하는 프로세스는 그 lock이 해제될때까지 계속 lock의 상태를 확인하며 대기&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;spin-lock&quot;&gt;Spin Lock&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;busy waiting이 적용된 mutex lock&lt;/li&gt;
  &lt;li&gt;busy waiting의 목적: 다른 프로세스에 CPU 자원을 뺏기지 않기 위해&lt;/li&gt;
  &lt;li&gt;장점: context switching overhead를 줄일 수 있다&lt;/li&gt;
  &lt;li&gt;단점: 프로세스가 lock을 소유하는 시간이 길면 비효율적이다&lt;/li&gt;
  &lt;li&gt;구현
    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  acquire(){
      while(!available){
          ; // busy waiting
      }
      available = false; // lock 획득
  }

  release(){
      available = true; // lock 해제
  }

  do{
      acquire();

      critical section

      release();

      remainder section
  } while(true);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;semaphore&quot;&gt;Semaphore&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;busy waiting이 필요없다&lt;/li&gt;
  &lt;li&gt;Semaphore S: 정수값. critical section 내에 한번에 진입 가능한 프로세스 수&lt;/li&gt;
  &lt;li&gt;P(), V() 연산: wait(), signal() 연산. 각각 lock을 얻고 lock을 해제하는 연산이다&lt;/li&gt;
  &lt;li&gt;구현
    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  wait(S){
      while(S &amp;lt;= 0){ // 현재 critical section에 들어갈 수 있는 자리가 없다
          ; // busy waiting
      }

      S--; // critical section 진입
  }

  signal(S){
      S++; // lock을 해제하고 critical section에서 나감
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;counting semaphore: critical section 내에 2개 이상의 프로세스가 동시에 진입 가능&lt;/li&gt;
  &lt;li&gt;binary semaphore: critical section 내에 1개의 프로세스만 동시에 진입 가능
    &lt;ul&gt;
      &lt;li&gt;mutex lock과 같다&lt;/li&gt;
      &lt;li&gt;wait(), signal()이 한 세마포어 안에서 동시에 일어날 수 없다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;semaphore without busy waiting
    &lt;ul&gt;
      &lt;li&gt;각각의 세마포어에는 waiting queue가 존재한다&lt;/li&gt;
      &lt;li&gt;block(): critical section에 빈자리가 없을때 critical section 진입을 요청하는 프로세스의 critical section 진입을 막는다&lt;/li&gt;
      &lt;li&gt;wakeup(): critical section에 빈자리가 있으면 대기중인 프로세스에 빈자리가 있음을 알린다&lt;/li&gt;
      &lt;li&gt;구현
        &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  typedef struct{
      int value; // 동시에 critical section에 진입 가능한 프로세스 수
      struct process* list; // critical section에 진입하려고 대기중인 프로세스 리스트
  } semaphore;

  wait(Semaphore *S){
      S-&amp;gt;value--;

      if(S-&amp;gt;value &amp;lt; 0){ // 현재 critical section에 빈자리가 없으면
          add this process to S-&amp;gt;list; // 프로세스를 세마포어 대기열로 보낸다
          block(); // 프로세스의 critical section을 막는다
      }
  }

  signal(Semaphore *S){
      S-&amp;gt;value++;

      if(S-&amp;gt;value &amp;lt;= 0){ // 현재 critical section에 진입하고자 하는 프로세스가 있으면
          remove a process P from S-&amp;gt;list; // 세마포어 대기열 맨 앞의 프로세스를 제거한다
          wakeup(P); // 그 프로세스에게 현재 critical section에 빈자리가 있음을 알린다
      }
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;deadlock--starvation&quot;&gt;Deadlock &amp;amp; Starvation&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Deadlock: 2개 이상의 프로세스가 각각의 자원을 점유한채 서로의 자원을 요청하는 현상 (점유 대기)&lt;/li&gt;
  &lt;li&gt;Starvation: 세마포어에 진입한 프로세스의 실행이 다른 프로세스에 의해 무한히 연기되는 현상 (indefinite blocking)&lt;/li&gt;
  &lt;li&gt;Priority Inversion: 우선순위가 낮은 프로세스가 우선순위가 높은 프로세스에게 필요한 lock을 점유한 상태
    &lt;ul&gt;
      &lt;li&gt;원인: Nonpreemptive regions of code, interrupt, synchronization, mutual exclusion&lt;/li&gt;
      &lt;li&gt;priority inheritance protocol로 해결&lt;/li&gt;
      &lt;li&gt;예
  &lt;img src=&quot;https://user-images.githubusercontent.com/23356503/56507038-0f062100-655b-11e9-8acc-422918558763.png&quot; alt=&quot;Priority Inversion&quot; /&gt;
        &lt;ul&gt;
          &lt;li&gt;세마포어 S1을 공유하는 T1, T3에 대해 S1과 상관없는 T2가 개입하여 priority inversion 발생&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;problems-of-synchronization&quot;&gt;Problems of Synchronization&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Bounded Buffer Problem
    &lt;ul&gt;
      &lt;li&gt;원소를 1개만 담을 수 있는 n개의 buffer 존재&lt;/li&gt;
      &lt;li&gt;Semaphore mutex: 초기값 1, full: 초기값 0, empty: 초기값 n&lt;/li&gt;
      &lt;li&gt;Producer
        &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  do{
      // Produce an item in next_produced
      ...
      wait(empty);
      wait(mutex);
      ...
      // Add next produced to buffer
      ...
      signal(mutex);
      signal(full);
  } while(true);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
        &lt;ul&gt;
          &lt;li&gt;빈 buffer를 채우고 full signal을 보내 lock 해제&lt;/li&gt;
          &lt;li&gt;buffer가 모두 차있다면 wait&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Consumer
        &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  do{
      wait(full); // 초기값이 0이다 =&amp;gt; producer가 채워놓기 전까지 계속 대기한다
      wait(mutex);
      ...
      // Remove an item from buffer to next_consumed
      ...
      signal(mutex);
      signal(empty);
      ...
      // Consume the item in next_consumed
      ...
  } while(true);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
        &lt;ul&gt;
          &lt;li&gt;buffer가 모두 full이면 item을 꺼내옴&lt;/li&gt;
          &lt;li&gt;buffer가 모두 empty면 empty signal을 보내 lock 해제&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Readers-Writers Problem
    &lt;ul&gt;
      &lt;li&gt;Readers: 읽기만 가능&lt;/li&gt;
      &lt;li&gt;Writers: 읽기, 쓰기 모두 가능&lt;/li&gt;
      &lt;li&gt;Problem
        &lt;ul&gt;
          &lt;li&gt;Reader는 몇명이 동시에 접근해도 상관없다&lt;/li&gt;
          &lt;li&gt;Writer: 동시에 하나의 writer만 접근할 수 있어야 한다&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Shared Data
        &lt;ul&gt;
          &lt;li&gt;Data Set&lt;/li&gt;
          &lt;li&gt;Semaphore rw_mutex: 초기값 1, mutex: 초기값 1&lt;/li&gt;
          &lt;li&gt;Integer read_count: 초기값 0&lt;/li&gt;
          &lt;li&gt;writer
            &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  do{
      wait(rw_mutex);
      ...
      // writing is performed
      ...
      signal(rw_mutex);
  } while(true);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;            &lt;/div&gt;
            &lt;ul&gt;
              &lt;li&gt;writer는 준비되었으면 즉시 writing을 수행해야 한다&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;reader
            &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  do{
      wait(mutex);
      read_count++;

      if(read_count == 1){
          wait(rw_mutex);
      }

      signal(mutex);
      ...
      // reading is performed
      ...
      wait(mutex);
      read_count--;

      if(read_count == 0){
          signal(rw_mutex);
      }
      signal(mutex);
  } while(true);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;            &lt;/div&gt;
            &lt;ul&gt;
              &lt;li&gt;writer가 작업중인 경우 어떠한 reader도 접근할 수 없다&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Dining Philosophers Problem
    &lt;ul&gt;
      &lt;li&gt;shared data
        &lt;ul&gt;
          &lt;li&gt;bowl of rice(data set)&lt;/li&gt;
          &lt;li&gt;semaphore chopstick[5] initialized to 1&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Philosopher i의 구조
        &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  do{
      wait(chopstick[i]); // 자기 왼쪽의 젓가락 집음
      wait(chopstick[(i+1) % 5]); // 바로 오른쪽의 젓가락 집음
      ...
      // eat
      ...
      signal(chopstick[i]);
      signal(chopstick[(i+1) % 5]);
  } while(true);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;</content><author><name>Jaehyun Keith Lee</name><email>wogus4187@naver.com</email></author><category term="Synchronization" /><summary type="html">Process Synchronization 필요성: 여러 프로세스 동시 실행시 공유되는 데이터의 일관성이 깨질 수 있다 race condition: 데이터에 어떤 프로세스가 먼저 접근하는지에 따라 결과가 달라지는 경우</summary></entry><entry><title type="html">Os_introduction</title><link href="keithlee94.github.io/KeithLog/os/OS_Introduction/" rel="alternate" type="text/html" title="Os_introduction" /><published>2019-04-21T00:00:00+00:00</published><updated>2019-04-21T00:00:00+00:00</updated><id>keithlee94.github.io/KeithLog/os/OS_Introduction</id><content type="html" xml:base="keithlee94.github.io/KeithLog/os/OS_Introduction/">&lt;h1 id=&quot;os의-역할&quot;&gt;OS의 역할&lt;/h1&gt;
&lt;ol&gt;
  &lt;li&gt;자원 관리&lt;/li&gt;
  &lt;li&gt;프로그램으로부터 컴퓨터가 손상되는것 방지&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;interrupt&quot;&gt;Interrupt&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;하드웨어 인터럽트: I/O 장치가 CPU에 이벤트 발생을 알리는 목적&lt;/li&gt;
  &lt;li&gt;소프트웨어 인터럽트: 프로그램 실행시 사용자 요청이나 에어로 인해 발생
    &lt;ul&gt;
      &lt;li&gt;예: trap, exception&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;ISR
    &lt;ul&gt;
      &lt;li&gt;Interrupt Service Routine&lt;/li&gt;
      &lt;li&gt;인터럽트 발생시 CPU가 자동으로 실행.&lt;/li&gt;
      &lt;li&gt;대부분의 인터럽트는 자신만의 ISR을 가지고 있다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;인터럽트 발생시&lt;/p&gt;

    &lt;ol&gt;
      &lt;li&gt;인터럽트가 발생한 프로세스의 Program Counter 정보 저장(현재까지 작업내용 저장)&lt;/li&gt;
      &lt;li&gt;ISR 실행하여 인터럽트 처리&lt;/li&gt;
      &lt;li&gt;Program Counter에서 정보 가져와 작업 재개&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;dma&quot;&gt;DMA&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;I/O 장치가 메모리에 빠르게 접근하기 위해 사용.&lt;/li&gt;
  &lt;li&gt;CPU의 개입 없이 버퍼를 통해 메모리에 바로 접근.
&lt;img src=&quot;https://user-images.githubusercontent.com/23356503/56469194-45677180-6471-11e9-8833-ecd3758fda5e.png&quot; alt=&quot;DMA&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;Synchronous I/O: I/O 작업이 끝나야 사용자 프로그램으로 제어가 넘어감.&lt;/li&gt;
  &lt;li&gt;Asynchronous I/O: I/O 작업 완료 전 사용자 프로그램으로 제어가 넘어감.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;저장공간&quot;&gt;저장공간&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;register - cache - main memory - ssd - magnetic disk - optical disk - magnetic tape 순으로 빠르다.&lt;/li&gt;
  &lt;li&gt;register, cache, main memory = volatile&lt;/li&gt;
  &lt;li&gt;캐싱: 속도가 더 빠른 저장공간에 사용할 데이터를 임시로 저장하는 것.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;process&quot;&gt;Process&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;현재 실행중인 프로그램&lt;/li&gt;
  &lt;li&gt;single thread: 1개의 Program Counter를 가진다.&lt;/li&gt;
  &lt;li&gt;multi thread: thread당 하나의 Program Counter를 갖는다.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;OS의 Process Management&lt;/p&gt;

    &lt;ol&gt;
      &lt;li&gt;user / system process 생성, 삭제&lt;/li&gt;
      &lt;li&gt;process 실행 중지, 재개&lt;/li&gt;
      &lt;li&gt;프로세스 동기화 mechanism 제공&lt;/li&gt;
      &lt;li&gt;프로세스간 통신 mechanism 제공&lt;/li&gt;
      &lt;li&gt;deadlock 처리를 위한 mechanism 제공&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ul&gt;</content><author><name>Jaehyun Keith Lee</name><email>wogus4187@naver.com</email></author><category term="Introduction" /><summary type="html">OS의 역할 자원 관리 프로그램으로부터 컴퓨터가 손상되는것 방지</summary></entry><entry><title type="html">Os_multithread</title><link href="keithlee94.github.io/KeithLog/os/OS_Multithread/" rel="alternate" type="text/html" title="Os_multithread" /><published>2019-04-21T00:00:00+00:00</published><updated>2019-04-21T00:00:00+00:00</updated><id>keithlee94.github.io/KeithLog/os/OS_Multithread</id><content type="html" xml:base="keithlee94.github.io/KeithLog/os/OS_Multithread/">&lt;h1 id=&quot;thread&quot;&gt;Thread&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;독립적으로 스케줄링되는 단위&lt;/li&gt;
  &lt;li&gt;프로세스 = 하나 이상의 같은 메모리 공간을 공유하는 쓰레드들로 구성&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;장점&lt;/p&gt;

    &lt;ol&gt;
      &lt;li&gt;반응성: 프로세스가 block되어도 영향 없음&lt;/li&gt;
      &lt;li&gt;자원 공유: 프로세스에 비해 자원공유가 간단&lt;/li&gt;
      &lt;li&gt;경제성: context switching overhead가 프로세스에 비해 적다&lt;/li&gt;
      &lt;li&gt;확장성: 멀티프로세서 장점 활용 가능&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;예: 서버가 클라이언트에 요청을 받으면 새 프로세스를 생성하는 대신 worker thread를 생성하여 요청 처리&lt;/li&gt;
  &lt;li&gt;구성
    &lt;ul&gt;
      &lt;li&gt;stack + register&lt;/li&gt;
      &lt;li&gt;같은 프로세스 내 쓰레드들끼리는 code, data, heap 공유&lt;/li&gt;
      &lt;li&gt;쓰레드 생성시 stack + register만 새로 생성됨&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;parallelism과-concurrency&quot;&gt;Parallelism과 Concurrency&lt;/h1&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Parallelism
- 동시에 2개 이상의 작업을 수행하는 시스템
- 멀티코어 구조에서만 가능
- Data Parallelism: 여러 프로세서에서 동일한 데이터로 동일한 작업 수행
- Task Parallelism: 여러 프로세서에서 서로 다른 쓰레드로 서로 다른 작업 수행

Concurrency
- 2개 이상의 작업이 동시에 진행될 수 있는 시스템
- 싱글코어 구조에서도 가능

차이
- Concurrency
    - 서로 다른 작업들을 중첩시켜 진행하는 방식
    - 여러 작업들이 있을때 한 작업이 끝나기 전 다른 작업 진행 가능
- Parallelism
    - 서로 다른 작업들을 동시에 여러개 처리하는 방식
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;multithreading&quot;&gt;Multithreading&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;User thread: user level thread library가 관리&lt;/li&gt;
  &lt;li&gt;Kernel thread: kernel이 관리&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;종류&lt;/p&gt;

    &lt;ol&gt;
      &lt;li&gt;Many to One
        &lt;ul&gt;
          &lt;li&gt;여러 user thread들이 하나의 kernel thread에 결합&lt;/li&gt;
          &lt;li&gt;하나의 thread가 block되면 다른 thread들도 block됨&lt;/li&gt;
          &lt;li&gt;하나의 kernel thread만이 처리 가능하므로 병렬 실행 불가&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;One to One
        &lt;ul&gt;
          &lt;li&gt;하나의 user thread가 하나의 kernel thread에 결합&lt;/li&gt;
          &lt;li&gt;user thread 생성시 연결할 kernel thread도 함께 생성&lt;/li&gt;
          &lt;li&gt;병렬 실행 가능&lt;/li&gt;
          &lt;li&gt;하나의 thread가 block되어도 다른 thread 실행 가능&lt;/li&gt;
          &lt;li&gt;context switching overhead 발생 가능&lt;/li&gt;
          &lt;li&gt;생성 가능한 thread 수 제한&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Many to Many
        &lt;ul&gt;
          &lt;li&gt;여러 user thread가 여러 kernel thread에 결합&lt;/li&gt;
          &lt;li&gt;kernel thread 생성 수 제한 없음&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Two level model
        &lt;ul&gt;
          &lt;li&gt;Many to Many + One to One 형태&lt;/li&gt;
          &lt;li&gt;중요도가 높은 user thread는 One to One 형태로 처리하여 선점권을 부여할 수 있다.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ul&gt;</content><author><name>Jaehyun Keith Lee</name><email>wogus4187@naver.com</email></author><category term="Multithread" /><summary type="html">Thread 독립적으로 스케줄링되는 단위 프로세스 = 하나 이상의 같은 메모리 공간을 공유하는 쓰레드들로 구성 장점</summary></entry><entry><title type="html">Os_process</title><link href="keithlee94.github.io/KeithLog/os/OS_Process/" rel="alternate" type="text/html" title="Os_process" /><published>2019-04-21T00:00:00+00:00</published><updated>2019-04-21T00:00:00+00:00</updated><id>keithlee94.github.io/KeithLog/os/OS_Process</id><content type="html" xml:base="keithlee94.github.io/KeithLog/os/OS_Process/">&lt;h1 id=&quot;process&quot;&gt;Process&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Program in execution&lt;/li&gt;
  &lt;li&gt;프로그램이 메모리에 올라오면 프로세스가 된다.&lt;/li&gt;
  &lt;li&gt;구성 요소
    &lt;ul&gt;
      &lt;li&gt;text section: program code&lt;/li&gt;
      &lt;li&gt;program counter&lt;/li&gt;
      &lt;li&gt;stack: 임시 데이터(로컬 변수 등) 저장&lt;/li&gt;
      &lt;li&gt;data section: 전역변수 저장&lt;/li&gt;
      &lt;li&gt;heap: 실행 도중 동적할당된 메모리 공간
&lt;img src=&quot;https://user-images.githubusercontent.com/23356503/56469277-80b67000-6472-11e9-89e4-70fe4c0288c4.png&quot; alt=&quot;Process Structure&quot; /&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;process-state&quot;&gt;Process State&lt;/h1&gt;
&lt;ol&gt;
  &lt;li&gt;new: 프로세스가 생성된 상태&lt;/li&gt;
  &lt;li&gt;ready: 프로세서에 할당되길 기다리는 상태&lt;/li&gt;
  &lt;li&gt;waiting: 프로세스가 event 발생을 기다리는 상태&lt;/li&gt;
  &lt;li&gt;running: 작업 수행&lt;/li&gt;
  &lt;li&gt;terminated: 작업 완료후 종료
    &lt;ul&gt;
      &lt;li&gt;new -&amp;gt; ready: 메모리에 올라감&lt;/li&gt;
      &lt;li&gt;ready -&amp;gt; running: CPU 자원 할당&lt;/li&gt;
      &lt;li&gt;running -&amp;gt; ready: 인터럽트 발생&lt;/li&gt;
      &lt;li&gt;running -&amp;gt; waiting: I/O 작업, event 발생&lt;/li&gt;
      &lt;li&gt;waiting -&amp;gt; ready: I/O 작업, event 완료&lt;/li&gt;
      &lt;li&gt;running -&amp;gt; terminated: exit 호출&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;pcb&quot;&gt;PCB&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Process Control Block&lt;/li&gt;
  &lt;li&gt;프로세스 정보 저장.
    &lt;ol&gt;
      &lt;li&gt;Process state&lt;/li&gt;
      &lt;li&gt;Program Counter: 프로세스가 다음에 실행할 명령어 주소를 가리킴&lt;/li&gt;
      &lt;li&gt;Process ID&lt;/li&gt;
      &lt;li&gt;CPU Register&lt;/li&gt;
      &lt;li&gt;CPU scheduling information: priority, scheduling queue pointers&lt;/li&gt;
      &lt;li&gt;Memory management information: memory allocated to process&lt;/li&gt;
      &lt;li&gt;Accounting information: CPU usage, clock time elapsed, time limits&lt;/li&gt;
      &lt;li&gt;I/O status information: I/O device allocated to process, list of open files&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;thread&quot;&gt;Thread&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;실행의 흐름&lt;/li&gt;
  &lt;li&gt;각 쓰레드당 하나의 PCB를 갖는다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;process-scheduling&quot;&gt;Process Scheduling&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;scheduling queue
    &lt;ul&gt;
      &lt;li&gt;job queue: 시스템의 모든 프로세스들의 집합&lt;/li&gt;
      &lt;li&gt;ready queue: 메인메모리에서 실행 대기중인 프로세스들의 집합&lt;/li&gt;
      &lt;li&gt;device queue: I/O 장치를 기다리는 프로세스들의 집합&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;scheduler: CPU가 다음에 실행할 프로세스 선택
    &lt;ul&gt;
      &lt;li&gt;long term: 어떤 프로세스를 ready queue에 넣을지 결정&lt;/li&gt;
      &lt;li&gt;short term: 어떤 프로세스에 CPU 자원을 할당할지 결정&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;I/O Bound Process: CPU 사용시간이 짧다. I/O에 치중.&lt;/li&gt;
  &lt;li&gt;CPU Bound Process: CPU 사용시간이 길다. 연산에 치중.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;context-switch&quot;&gt;Context Switch&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;CPU가 프로세스 전환시 이전 프로세스 상태를 저장하고 새로운 프로세스의 상태 정보를 불러오는 작업.&lt;/li&gt;
  &lt;li&gt;Context: 프로세스 상태 정보. PCB에 저장.&lt;/li&gt;
  &lt;li&gt;Overhead 발생: context switching동안 시스템이 다른 작업을 할 수 없다.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;순서&lt;/p&gt;

    &lt;ol&gt;
      &lt;li&gt;현재 진행중인 프로세스 정보 PCB에 저장&lt;/li&gt;
      &lt;li&gt;새로 실행할 프로세스의 PCB 정보 불러옴&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;process-creation&quot;&gt;Process Creation&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;부모프로세스가 자식프로세스 생성&lt;/li&gt;
  &lt;li&gt;pid: 프로세스간 구별을 위해 사용&lt;/li&gt;
  &lt;li&gt;자원 공유: 부모와 자식간 자원 공유 가능&lt;/li&gt;
  &lt;li&gt;실행 옵션
    &lt;ul&gt;
      &lt;li&gt;부모가 자식 끝나기까지 기다림&lt;/li&gt;
      &lt;li&gt;부모와 자식이 동시에 실행&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;fork()
    &lt;ul&gt;
      &lt;li&gt;새로운 프로세스를 만드는 시스템 콜&lt;/li&gt;
      &lt;li&gt;부모와 완전히 동일한 자식 프로세스 생성&lt;/li&gt;
      &lt;li&gt;pid_t 타입의 pid 리턴
        &lt;ul&gt;
          &lt;li&gt;음수: fork() 실패&lt;/li&gt;
          &lt;li&gt;0: 자식 프로세스&lt;/li&gt;
          &lt;li&gt;자연수: 부모 프로세스&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;exec()
    &lt;ul&gt;
      &lt;li&gt;생성된 자식 프로세스의 context 변경을 위한 시스템 콜&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/23356503/56469481-5619e680-6475-11e9-9ca2-2d28e3ee9f39.png&quot; alt=&quot;Process Creation&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;process-termination&quot;&gt;Process Termination&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;exit()
    &lt;ul&gt;
      &lt;li&gt;프로세스가 실행을 끝내고 OS에 프로세스 삭제를 요청하는 시스템 콜&lt;/li&gt;
      &lt;li&gt;프로세스에 할당된 자원 반환&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;abort()
    &lt;ul&gt;
      &lt;li&gt;부모 프로세스가 자식 프로세스를 종료시키는 시스템 콜&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;zombie process: 종료된 프로세스를 기다리는 부모 프로세스가 없는 프로세스&lt;/li&gt;
  &lt;li&gt;orphan process: 부모 프로세스가 실행 완료 전 종료된 프로세스&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;ipc&quot;&gt;IPC&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;InterProcess Communication: 프로세스간 통신을 위해 필요&lt;/li&gt;
  &lt;li&gt;Shared Memory
  &lt;img src=&quot;https://user-images.githubusercontent.com/23356503/56469538-215a5f00-6476-11e9-984c-33f601c6e3f0.png&quot; alt=&quot;Shared Memory&quot; /&gt;
    &lt;ul&gt;
      &lt;li&gt;장점: 메모리에 곧바로 접근하므로 속도가 빠르다&lt;/li&gt;
      &lt;li&gt;단점: 동기화가 어렵다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Message Passing
  &lt;img src=&quot;https://user-images.githubusercontent.com/23356503/56469567-96c62f80-6476-11e9-87af-6f153a671e56.png&quot; alt=&quot;Message Passing&quot; /&gt;
    &lt;ul&gt;
      &lt;li&gt;장점: 동기화가 쉽다&lt;/li&gt;
      &lt;li&gt;단점: 커널에 의존하므로 속도가 느리다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;message-passing&quot;&gt;Message Passing&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;send, receive 기능 제공&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;과정&lt;/p&gt;

    &lt;ol&gt;
      &lt;li&gt;소통하려는 두 프로세스 간 communication link 개설&lt;/li&gt;
      &lt;li&gt;send, receive를 통해 메시지 교환&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;Direct Communication
    &lt;ul&gt;
      &lt;li&gt;어떤 프로세스에게 메시지를 보내거나 받을지 명시&lt;/li&gt;
      &lt;li&gt;link가 자동으로 생성됨&lt;/li&gt;
      &lt;li&gt;하나의 link는 한쌍의 프로세스만 연결, 한쌍의 프로세스 간에는 하나의 link만 존재&lt;/li&gt;
      &lt;li&gt;bidirectional&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Indirect Communication
    &lt;ul&gt;
      &lt;li&gt;mailbox(port)를 통해 메시지를 주고받음&lt;/li&gt;
      &lt;li&gt;프로세스간 mailbox를 공유한 경우에만 소통 가능&lt;/li&gt;
      &lt;li&gt;프로세스간 mailbox 공유시에만 link 생성&lt;/li&gt;
      &lt;li&gt;하나의 link에 여러 프로세스 연결 가능, 한쌍의 프로세스 간 여러 link 존재 가능&lt;/li&gt;
      &lt;li&gt;unidirectional, bidirectional&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Synchronization
    &lt;ul&gt;
      &lt;li&gt;blocking send: 메시지 수신 전까지 sender block&lt;/li&gt;
      &lt;li&gt;nonblocking send: block 없이 sender가 메시지 전송&lt;/li&gt;
      &lt;li&gt;blocking receive: 메시지가 들어오기 전까지 receiver block&lt;/li&gt;
      &lt;li&gt;nonblocking receive: block 없이 receiver가 메시지 수신 = 메시지가 null일 수 있다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;</content><author><name>Jaehyun Keith Lee</name><email>wogus4187@naver.com</email></author><category term="Process" /><summary type="html">Process Program in execution 프로그램이 메모리에 올라오면 프로세스가 된다. 구성 요소 text section: program code program counter stack: 임시 데이터(로컬 변수 등) 저장 data section: 전역변수 저장 heap: 실행 도중 동적할당된 메모리 공간</summary></entry><entry><title type="html">Os_process_scheduling</title><link href="keithlee94.github.io/KeithLog/os/OS_Process_Scheduling/" rel="alternate" type="text/html" title="Os_process_scheduling" /><published>2019-04-21T00:00:00+00:00</published><updated>2019-04-21T00:00:00+00:00</updated><id>keithlee94.github.io/KeithLog/os/OS_Process_Scheduling</id><content type="html" xml:base="keithlee94.github.io/KeithLog/os/OS_Process_Scheduling/">&lt;h1 id=&quot;cpu-scheduling&quot;&gt;CPU Scheduling&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;발생 경우&lt;/p&gt;

    &lt;ol&gt;
      &lt;li&gt;프로세스가 running -&amp;gt; waiting으로 전환 - Nonpreemptive&lt;/li&gt;
      &lt;li&gt;프로세스가 running -&amp;gt; ready로 전환 - Preemptive&lt;/li&gt;
      &lt;li&gt;프로세스가 waiting -&amp;gt; ready로 전환 - Preemptive&lt;/li&gt;
      &lt;li&gt;프로세스 종료 - Nonpreemptive&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;Preemptive
    &lt;ul&gt;
      &lt;li&gt;현재 CPU를 할당받은 프로세스가 다른 프로세스에 자원을 내줄 수 있음&lt;/li&gt;
      &lt;li&gt;문제: race condition - 데이터를 공유하는 경우, 커널모드에서 preemption 발생, OS의 중요 작업중 인터럽트 발생&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Nonpreemptive
    &lt;ul&gt;
      &lt;li&gt;CPU 자원을 할당받은 프로세스가 직접 자원을 반납하기 전까지 계속 자원 점유&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;scheduling-criteria&quot;&gt;Scheduling Criteria&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;CPU Utilization: CPU를 idle 상태로 두지 않는 것. (Maximize)&lt;/li&gt;
  &lt;li&gt;Throughput: 단위시간 동안 끝낼 수 있는 프로세스 수 (Maximize)&lt;/li&gt;
  &lt;li&gt;Turnaround time: 특정 프로세스 실행까지 걸리는 시간 (Minimize)&lt;/li&gt;
  &lt;li&gt;Waiting time: 프로세스가 ready queue에서 대기한 시간 (Minimize)&lt;/li&gt;
  &lt;li&gt;Response time: 프로세스 실행 요청 생성 후 첫 response가 올때까지 걸린 시간 (Minimize)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;fcfs-scheduling&quot;&gt;FCFS Scheduling&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;First Come First Served&lt;/li&gt;
  &lt;li&gt;프로세스 도착 순서대로 CPU 자원 할당.&lt;/li&gt;
  &lt;li&gt;문제점: convoy effect
    &lt;ul&gt;
      &lt;li&gt;실행시간이 짧은 프로세스가 긴 프로세스에 막혀 대기시간이 길어질 수 있다&lt;/li&gt;
      &lt;li&gt;예: I/O bound process가 많은 경우&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;sjf-scheduling&quot;&gt;SJF Scheduling&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Shortest Job Fisrt&lt;/li&gt;
  &lt;li&gt;실행시간(CPU Burst time)이 짧은 프로세스를 먼저 실행한다&lt;/li&gt;
  &lt;li&gt;Optimal: 평균 대기시간이 가장 짧다&lt;/li&gt;
  &lt;li&gt;문제점: 각각의 프로세스들의 실행시간을 알아내기 어렵다&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;srtf-scheduling&quot;&gt;SRTF Scheduling&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Shortest Remaining Time First&lt;/li&gt;
  &lt;li&gt;SJF의 Preemptive 버전&lt;/li&gt;
  &lt;li&gt;단위시간마다 각 프로세스들의 작업 완료까지 남은 시간을 계산하여 남은시간이 가장 짧은 프로세스를 실행한다&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;priority-scheduling&quot;&gt;Priority Scheduling&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;각각의 프로세스에 우선순위 부여&lt;/li&gt;
  &lt;li&gt;SJF = CPU Burst time이 짧을수록 높은 우선순위&lt;/li&gt;
  &lt;li&gt;문제점: Starvation
    &lt;ul&gt;
      &lt;li&gt;우선순위가 낮은 프로세스가 높은 프로세스에 밀려 무한히 대기하는 현상&lt;/li&gt;
      &lt;li&gt;해결: Aging - 대기한 시간에 따라 우선순위 상향 조정&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;round-robin&quot;&gt;Round Robin&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;각각의 프로세스에 실행시간(Time Quantum) 부여&lt;/li&gt;
  &lt;li&gt;프로세스 실행중 Time Quantum이 다 지나면 다른 프로세스에 의해 preemption되고 ready queue의 맨 뒤로 옮겨간다&lt;/li&gt;
  &lt;li&gt;Starvation 문제 해결&lt;/li&gt;
  &lt;li&gt;매 quantum마다 timer interrupt 발생&lt;/li&gt;
  &lt;li&gt;성능
    &lt;ul&gt;
      &lt;li&gt;q가 크면: FCFS와 유사(비효율적)&lt;/li&gt;
      &lt;li&gt;q가 작으면: response time이 빨라지나 context switching overhead가 커진다&lt;/li&gt;
      &lt;li&gt;SJF에 비해 turnaround time이 길지만 response가 더 뛰어나다&lt;/li&gt;
      &lt;li&gt;q 설정: context switching에 걸리는 시간보다 길게 설정&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;multilevel-queue&quot;&gt;Multilevel Queue&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Ready Queue를 여러 큐로 나누는 방식&lt;/li&gt;
  &lt;li&gt;foreground: interactive processes (Round Robin)&lt;/li&gt;
  &lt;li&gt;background: batch processes (FCFS)&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;우선순위&lt;/p&gt;

    &lt;ol&gt;
      &lt;li&gt;System processes&lt;/li&gt;
      &lt;li&gt;interactive processes&lt;/li&gt;
      &lt;li&gt;interactive editing processes&lt;/li&gt;
      &lt;li&gt;batch processes&lt;/li&gt;
      &lt;li&gt;student processess&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;multilevel-feedback-queue&quot;&gt;Multilevel Feedback Queue&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;프로세스가 현재 큐에서 다른 큐로 이동 가능&lt;/li&gt;
  &lt;li&gt;큐별로 다른 quantum 적용 가능&lt;/li&gt;
  &lt;li&gt;한 큐에서 quantum 내에 작업이 끝나지 않았으면 다음 큐로 이동하는 방식&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;multiple-processor-scheduling&quot;&gt;Multiple Processor Scheduling&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Asymmetric Multiprocessing: 한 프로세서만 시스템 데이터 구조에 접근하여 데이터 공유의 필요성을 줄인다&lt;/li&gt;
  &lt;li&gt;Symmetric Multiprocessing: 각각의 프로세서가 각자 스케줄링을 실행하고 모든 프로세스들이 하나의 ready queue를 공유하거나 각자 다른 ready queue를 갖는 구조&lt;/li&gt;
  &lt;li&gt;Affinity: 특정 코어를 지정하여 task를 수행하도록 하는 설계&lt;/li&gt;
  &lt;li&gt;NUMA
    &lt;ul&gt;
      &lt;li&gt;Non Uniform Memory Access&lt;/li&gt;
      &lt;li&gt;CPU에 묶여있는 메모리에 대해서는 접근 속도가 빠르고, 다른 CPU에 묶여있는 메모리에 대해서는 접근 속도가 느리다&lt;/li&gt;
      &lt;li&gt;Affinity를 고려하여 메모리 배치&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Load Balancing
    &lt;ul&gt;
      &lt;li&gt;작업을 여러 프로세서에 고르게 분산시킨다&lt;/li&gt;
      &lt;li&gt;Push migration: 주기적으로 프로세서들의 작업량을 확인하여 작업이 많은 프로세서의 작업을 작업이 적은 프로세서로 옮긴다&lt;/li&gt;
      &lt;li&gt;Pull migration: 작업이 적은 프로세서가 작업이 많은 프로세서의 작업을 가져온다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;multithread-multicore-system&quot;&gt;Multithread Multicore System&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Memory stall: 프로세서가 요청한 데이터가 메모리로부터 도착하기까지 기다리는 시간&lt;/li&gt;
  &lt;li&gt;Multithread Processor 구조: 2개 이상의 하드웨어 쓰레드가 각각의 코어에 할당되어 하나의 쓰레드에서 memory stall 발생시 다른 쓰레드로 전환하여 작업 처리&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Jaehyun Keith Lee</name><email>wogus4187@naver.com</email></author><category term="Process Scheduling" /><summary type="html">CPU Scheduling 발생 경우 프로세스가 running -&amp;gt; waiting으로 전환 - Nonpreemptive 프로세스가 running -&amp;gt; ready로 전환 - Preemptive 프로세스가 waiting -&amp;gt; ready로 전환 - Preemptive 프로세스 종료 - Nonpreemptive Preemptive 현재 CPU를 할당받은 프로세스가 다른 프로세스에 자원을 내줄 수 있음 문제: race condition - 데이터를 공유하는 경우, 커널모드에서 preemption 발생, OS의 중요 작업중 인터럽트 발생 Nonpreemptive CPU 자원을 할당받은 프로세스가 직접 자원을 반납하기 전까지 계속 자원 점유</summary></entry><entry><title type="html">2098</title><link href="keithlee94.github.io/KeithLog/algorithm/2098/" rel="alternate" type="text/html" title="2098" /><published>2019-04-04T00:00:00+00:00</published><updated>2019-04-04T00:00:00+00:00</updated><id>keithlee94.github.io/KeithLog/algorithm/2098</id><content type="html" xml:base="keithlee94.github.io/KeithLog/algorithm/2098/">&lt;h1 id=&quot;백준-2098번&quot;&gt;백준 2098번&lt;/h1&gt;
&lt;p&gt;Link: &lt;a href=&quot;https://www.acmicpc.net/problem/2098&quot;&gt;2098번: 외판원 순회&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;문제-설명&quot;&gt;문제 설명&lt;/h1&gt;
&lt;p&gt;그 유명한 Traveling Salesperson 문제다.&lt;/p&gt;

&lt;p&gt;NP-hard 문제지만, 여기서는 인풋이 좀 작아서 시간안에 풀리도록 만들었다.&lt;/p&gt;

&lt;p&gt;푸는 방법은 사실 단순한데, DFS + Memoization으로 풀면 된다.&lt;/p&gt;

&lt;p&gt;그런데 여기서 중요한 점이 하나 있는데, 출발점을 제외한 모든 도시들은 단 한번만 방문할 수 있다는 점이다.&lt;/p&gt;

&lt;p&gt;이 방문 여부를 표시하기 위해 비트마스킹을 사용한다는 점이 큰 차이점이다.&lt;/p&gt;

&lt;p&gt;처음에는 비트마스킹을 안쓰고 단순 DP로만 풀어보려고 했는데, 어떻게 푸는지는 알겠는데 도저히 구현이 안되더라.&lt;/p&gt;

&lt;p&gt;겨우겨우 구현해서 제출해보니 역시나 틀린 답이었다.&lt;/p&gt;

&lt;p&gt;한참 더 고민하다 답을 찾아봤고, 단순 DP로 풀리는 문제가 아니라는 점을 깨달았다.&lt;/p&gt;

&lt;p&gt;푸는 방법은 다음과 같다.&lt;/p&gt;

&lt;p&gt;우선 DFS 함수의 인자를 인덱스와 방문 여부로 받도록 한다.&lt;/p&gt;

&lt;p&gt;여기에 0과 1을 넘겨, 첫 도시에서 시작한다는 점을 명시하여 DFS 함수를 실행한다.&lt;/p&gt;

&lt;p&gt;DFS 함수의 종료 조건은 모든 도시를 방문했다는 경우로, visit이 1을 N만큼 왼쪽으로 shift한 값 - 1과 같은 값이 되면 종료한다.&lt;/p&gt;

&lt;p&gt;이때 그냥 종료하면 안되고, 마지막 방문 도시에서 처음 도시로 가는 길이 없다면 불가능한 경우이므로 무한대값을 리턴한다.&lt;/p&gt;

&lt;p&gt;길이 있다면 그 길을 택했을때의 cost 값을 리턴한다.&lt;/p&gt;

&lt;p&gt;종료조건이 아닐 경우, 현재 인덱스 값과 visit을 통해 DP 배열의 값을 받아온다.&lt;/p&gt;

&lt;p&gt;이때 중요한 점은 DP 배열의 값을 받아오는 것이 아닌 &lt;b&gt;주소값을 받아와야 한다&lt;/b&gt;는 것. 이렇게 하면 DP 배열을 일일이 갱신하지 않고 주소값을 받아온 변수를 변경하면 알아서 DP배열의 값도 바뀐다.&lt;/p&gt;

&lt;p&gt;포인터 연산의 편리함을 다시한번 느끼게 된 계기.&lt;/p&gt;

&lt;p&gt;이렇게 받아온 값이 초기값인 -1이 아니라면 이 값을 그대로 리턴해준다.&lt;/p&gt;

&lt;p&gt;만약 초기값에서 갱신되지 않았다면, 우선 매우 큰 값으로 설정해 준다.&lt;/p&gt;

&lt;p&gt;그 다음, 현재 위치에서 연결되었으며 앞에서 방문하지 않은 도시들에 대해 재귀함수로 탐색하며 최소값을 갱신해 준다. 이때 방문 여부를 1을 도시 번호만큼 왼쪽으로 shift하여 표시한다.&lt;/p&gt;

&lt;p&gt;이렇게 재귀함수를 돌며 갱신된 값이 곧 답이다.&lt;/p&gt;

&lt;p&gt;재귀함수를 돌며 탐색하는 부분이 가장 이해하기 어려웠는데, 순열을 재귀로 만드는 과정과 같다고 생각하면 이해가 빠르다.&lt;/p&gt;

&lt;p&gt;모든 경우를 다 따져가며 최소값을 구하고, 탐색 결과값을 저장하고 이를 불러옴으로써 시간을 단축시킬 수 있는 문제.&lt;/p&gt;

&lt;p&gt;앞으로도 문제풀때 중요한 개념들이 여럿 등장했던 중요한 문제다.&lt;/p&gt;

&lt;p&gt;비트마스킹, 포인터 연산이 아주 중요한 개념임을 깨닫게 된 문제.&lt;/p&gt;

&lt;p&gt;꼭 다시한번 풀어봐야될 문제인 것 같다.&lt;/p&gt;
&lt;hr /&gt;

&lt;h1 id=&quot;정답-코드&quot;&gt;정답 코드&lt;/h1&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;//
// Created by Keith_Lee on 04/04/2019.
//

#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string.h&amp;gt;

using namespace std;

int map[16][16] = {0, };
int DP[16][1 &amp;lt;&amp;lt; 16] = {0, };

int N;

int cost(int index, int visit){
    if(visit == (1 &amp;lt;&amp;lt; N) - 1){
        if(map[index][0] == 0){
            return 987654321;
        }

        return map[index][0];
    }

    int&amp;amp; result = DP[index][visit];

    if(result != -1){
        return result;
    }

    result = 999999999;

    for(int i=0; i&amp;lt;N; i++){
        if(visit &amp;amp; (1 &amp;lt;&amp;lt; i) || map[index][i] == 0){
            continue;
        }

        result = min(result, cost(i, (visit | (1 &amp;lt;&amp;lt; i))) + map[index][i]);
    }

    return result;
}

int main(){
    cin &amp;gt;&amp;gt; N;

    for(int i=0; i&amp;lt;N; i++){
        for(int j=0; j&amp;lt;N; j++){
            cin &amp;gt;&amp;gt; map[i][j];
        }
    }

    memset(DP, -1, sizeof(DP));

    cout &amp;lt;&amp;lt; cost(0, 1) &amp;lt;&amp;lt; '\n';

    return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;hr /&gt;</content><author><name>Jaehyun Keith Lee</name><email>wogus4187@naver.com</email></author><category term="DP" /><category term="Bit Masking" /><summary type="html">백준 2098번 Link: 2098번: 외판원 순회</summary></entry><entry><title type="html">2206</title><link href="keithlee94.github.io/KeithLog/algorithm/2206/" rel="alternate" type="text/html" title="2206" /><published>2019-04-04T00:00:00+00:00</published><updated>2019-04-04T00:00:00+00:00</updated><id>keithlee94.github.io/KeithLog/algorithm/2206</id><content type="html" xml:base="keithlee94.github.io/KeithLog/algorithm/2206/">&lt;h1 id=&quot;백준-2206번&quot;&gt;백준 2206번&lt;/h1&gt;
&lt;p&gt;Link: &lt;a href=&quot;https://www.acmicpc.net/problem/2206&quot;&gt;2206번: 벽 부수고 이동하기&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;문제-설명&quot;&gt;문제 설명&lt;/h1&gt;
&lt;p&gt;예전에 한번 풀어봤던 벽부수고 이동하는 문제.&lt;/p&gt;

&lt;p&gt;간만에 다시한번 풀어봤는데, 그때 답보고 풀어서 그런지 다시봐도 새롭더라.&lt;/p&gt;

&lt;p&gt;여러번 거치다 보니 BFS로 거리 구하는 틀이 거의 정형화됐는데, 예전에는 visit 배열을 만드는 대신 거리를 계산하는 배열을 만들어서 거리를 쟀었다.&lt;/p&gt;

&lt;p&gt;이 문제도 그렇게 풀었는데, 거리 계산 배열을 3차원으로 만들어 벽을 안부쉈을 경우와 부쉈을 경우로 나눠 거리를 구한다.&lt;/p&gt;

&lt;p&gt;큐에도 출발점과 벽 부술수 있는 횟수를 넣고 출발하는데, 만약 목적지에 도착했다면 거리 배열[x][y][남은 부술수있는 횟수] 값을 리턴해준다.&lt;/p&gt;

&lt;p&gt;이외에는 BFS와 크게 다르지 않은데, 벽을 안부수고 0을 찾아 이동한 거리를 구해주고, 부술 수 있는 횟수가 남았으면 벽을 부수고 이동한 거리를 구한 다음 부술 수 있는 횟수를 1 빼준다.&lt;/p&gt;

&lt;p&gt;이런식으로 목적지까지 찾아가서 남은 부술수 있는 횟수에 대한 거리를 구하면 끝.&lt;/p&gt;

&lt;p&gt;이번에서야 예전 답을 좀 이해할 수 있을 것 같다.&lt;/p&gt;

&lt;p&gt;다음에도 한번 더 풀어봐야지.&lt;/p&gt;
&lt;hr /&gt;

&lt;h1 id=&quot;정답-코드&quot;&gt;정답 코드&lt;/h1&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;//
// Created by Keith_Lee on 03/04/2019.
//

#include &amp;lt;iostream&amp;gt;
#include &amp;lt;queue&amp;gt;

using namespace std;

struct Point{
    int x, y;
    int breakCount;
};

int map[1000][1000] = {0, };
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
int dist[1000][1000][2] = {0, };

int N, M;

int BFS(){
    queue&amp;lt;Point&amp;gt; Queue;
    Queue.push({0, 0, 1});
    dist[0][0][1] = 1;

    while(!Queue.empty()){
        int currentX = Queue.front().x;
        int currentY = Queue.front().y;
        int breakCount = Queue.front().breakCount;
        Queue.pop();

        if(currentX == N-1 &amp;amp;&amp;amp; currentY == M-1){
            return dist[N-1][M-1][breakCount];
        }

        for(int i=0; i&amp;lt;4; i++){
            int nextX = currentX + dx[i];
            int nextY = currentY + dy[i];

            if(nextX &amp;gt;= 0 &amp;amp;&amp;amp; nextX &amp;lt; N &amp;amp;&amp;amp; nextY &amp;gt;= 0 &amp;amp;&amp;amp; nextY &amp;lt; M){
                if(map[nextX][nextY] == 0 &amp;amp;&amp;amp; dist[nextX][nextY][breakCount] == 0){
                    dist[nextX][nextY][breakCount] = dist[currentX][currentY][breakCount] + 1;
                    Queue.push({nextX, nextY, breakCount});
                }
                else if(map[nextX][nextY] == 1 &amp;amp;&amp;amp; breakCount &amp;gt; 0){
                    dist[nextX][nextY][breakCount-1] = dist[currentX][currentY][breakCount] + 1;
                    Queue.push({nextX, nextY, breakCount-1});
                }
            }
        }
    }

    return -1;
}

int main(){
    cin &amp;gt;&amp;gt; N &amp;gt;&amp;gt; M;

    for(int i=0; i&amp;lt;N; i++){
        string row;
        cin &amp;gt;&amp;gt; row;

        for(int j=0; j&amp;lt;M; j++){
            map[i][j] = row[j] - '0';
        }
    }

    cout &amp;lt;&amp;lt; BFS() &amp;lt;&amp;lt; '\n';

    return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;hr /&gt;</content><author><name>Jaehyun Keith Lee</name><email>wogus4187@naver.com</email></author><category term="BFS" /><summary type="html">백준 2206번 Link: 2206번: 벽 부수고 이동하기</summary></entry><entry><title type="html">10610</title><link href="keithlee94.github.io/KeithLog/algorithm/10610/" rel="alternate" type="text/html" title="10610" /><published>2019-04-02T00:00:00+00:00</published><updated>2019-04-02T00:00:00+00:00</updated><id>keithlee94.github.io/KeithLog/algorithm/10610</id><content type="html" xml:base="keithlee94.github.io/KeithLog/algorithm/10610/">&lt;h1 id=&quot;백준-10610번&quot;&gt;백준 10610번&lt;/h1&gt;
&lt;p&gt;Link: &lt;a href=&quot;https://www.acmicpc.net/problem/10610&quot;&gt;10610번: 30&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;문제-설명&quot;&gt;문제 설명&lt;/h1&gt;
&lt;p&gt;예전에 실패했던 문제여서 다시한번 풀어본 문제.&lt;/p&gt;

&lt;p&gt;너무 허무할정도로 쉽게 답이 나와버려서 이걸 도대체 왜 못풀었을까 하는 생각이 들게 하는 문제였다.&lt;/p&gt;

&lt;p&gt;우선 인풋을 string 형태로 받고, 각 자리수를 모두 더해 3의 배수가 되는지 확인한다. 이때 0의 갯수를 세주는 작업도 같이 한다.&lt;/p&gt;

&lt;p&gt;작업 중 0이 아닌 숫자를 만날 경우 벡터에 넣는다.&lt;/p&gt;

&lt;p&gt;반복문을 한번 돌고 나서, 벡터를 정렬한다. 내림차순으로 정렬되므로 끝에서부터 쭉 결과값을 담을 string에 넣는다.&lt;/p&gt;

&lt;p&gt;만약 인풋으로 들어온 숫자가 3의 배수가 아니거나 0을 포함하지 않았다면 -1을 출력하고, 그렇지 않을 경우 만든 string을 출력하면 풀린다.&lt;/p&gt;

&lt;p&gt;에전이랑 생각하는게 많이 달라졌나보다. 이런문제도 못풀었나 하는 생각이 들 정도면.&lt;/p&gt;

&lt;p&gt;그동안 많이 발전했다는 기분에 뿌듯하네ㅋㅋㅋㅋ&lt;/p&gt;
&lt;hr /&gt;

&lt;h1 id=&quot;정답-코드&quot;&gt;정답 코드&lt;/h1&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;//
// Created by Keith_Lee on 02/04/2019.
//

#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;vector&amp;gt;

using namespace std;

int main(){
    string num;
    cin &amp;gt;&amp;gt; num;

    int zeroCount = 0;
    long long digitSum = 0;
    vector&amp;lt;int&amp;gt; numbers;

    for(int i=num.length()-1; i&amp;gt;=0; i--){
        if(num[i] - '0' == 0){
            zeroCount++;
        }
        else{
            numbers.push_back(num[i] - '0');
            digitSum += num[i] - '0';
        }
    }

    sort(numbers.begin(), numbers.end());

    string result;
    if(zeroCount &amp;gt; 0 &amp;amp;&amp;amp; digitSum % 3 == 0){
        for(int i=numbers.size()-1; i&amp;gt;=0; i--){
            result.push_back(numbers[i] + '0');
        }
        for(int i=0; i&amp;lt;zeroCount; i++){
            result.push_back('0');
        }

        cout &amp;lt;&amp;lt; result &amp;lt;&amp;lt; '\n';
    }
    else{
        cout &amp;lt;&amp;lt; -1 &amp;lt;&amp;lt; '\n';
    }

    return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;hr /&gt;</content><author><name>Jaehyun Keith Lee</name><email>wogus4187@naver.com</email></author><category term="Greedy" /><summary type="html">백준 10610번 Link: 10610번: 30</summary></entry><entry><title type="html">1018</title><link href="keithlee94.github.io/KeithLog/algorithm/1018/" rel="alternate" type="text/html" title="1018" /><published>2019-04-01T00:00:00+00:00</published><updated>2019-04-01T00:00:00+00:00</updated><id>keithlee94.github.io/KeithLog/algorithm/1018</id><content type="html" xml:base="keithlee94.github.io/KeithLog/algorithm/1018/">&lt;h1 id=&quot;백준-1018번&quot;&gt;백준 1018번&lt;/h1&gt;
&lt;p&gt;Link: &lt;a href=&quot;https://www.acmicpc.net/problem/1018&quot;&gt;1018번: 체스판 다시 칠하기&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;문제-설명&quot;&gt;문제 설명&lt;/h1&gt;
&lt;p&gt;오랫만에 풀어보는 시뮬레이션 문제였다.&lt;/p&gt;

&lt;p&gt;사실 별건 없어서, 엄청 큰 체스판에 대해 옆으로, 아래로 한칸씩 옮겨가면서 왼쪽 위 코너가 흰색인 체스판과 검은색인 체스판에 대해 맞춰보며 다시 칠하는 횟수가 최소인 경우의 최소값을 찾으면 되는 문제다.&lt;/p&gt;

&lt;p&gt;그냥 단순히 반복문 돌리면서 비교하면 답 나옴.&lt;/p&gt;
&lt;hr /&gt;

&lt;h1 id=&quot;정답-코드&quot;&gt;정답 코드&lt;/h1&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;//
// Created by Keith_Lee on 01/04/2019.
//

#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;algorithm&amp;gt;

using namespace std;

char board1[8][8] = {
        {'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B'},
        {'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W'},
        {'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B'},
        {'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W'},
        {'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B'},
        {'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W'},
        {'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B'},
        {'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W'}
};

char board2[8][8] = {
        {'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W'},
        {'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B'},
        {'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W'},
        {'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B'},
        {'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W'},
        {'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B'},
        {'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W'},
        {'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B'}
};

char map[50][50];

int main(){
    int N, M;

    cin &amp;gt;&amp;gt; N &amp;gt;&amp;gt; M;

    for(int i=0; i&amp;lt;N; i++){
        string row;
        cin &amp;gt;&amp;gt; row;

        for(int j=0; j&amp;lt;M; j++){
            map[i][j] = row[j];
        }
    }

    char checkMap[8][8];
    vector&amp;lt;int&amp;gt; candidates;

    for(int i=0; i&amp;lt;N; i++){
        for(int j=0; j&amp;lt;M; j++){
            if(i + 7 &amp;lt; N &amp;amp;&amp;amp; j + 7 &amp;lt; M){
                for(int k=0; k&amp;lt;8; k++){
                    for(int l=0; l&amp;lt;8; l++){
                        checkMap[k][l] = map[k+i][l+j];
                    }
                }

                int result1 = 0, result2 = 0;
                for(int k=0; k&amp;lt;8; k++){
                    for(int l=0; l&amp;lt;8; l++){
                        if(checkMap[k][l] != board1[k][l]){
                            result1++;
                        }
                        if(checkMap[k][l] != board2[k][l]){
                            result2++;
                        }
                    }
                }

                candidates.push_back(result1);
                candidates.push_back(result2);
            }
        }
    }

    sort(candidates.begin(), candidates.end());

    cout &amp;lt;&amp;lt; candidates[0] &amp;lt;&amp;lt; '\n';

    return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;hr /&gt;</content><author><name>Jaehyun Keith Lee</name><email>wogus4187@naver.com</email></author><category term="Simulation" /><category term="Brute Force" /><summary type="html">백준 1018번 Link: 1018번: 체스판 다시 칠하기</summary></entry></feed>