[OS]臨界領域問題


りんかいいきもんだい



臨界領域とは?


臨界領域:マルチスレッドシステムでスレッドによって共通変数を変更したり、テーブルを更新したり、ファイルに書き込まれたりしたコードの一部.すなわち、共有リソースのコードにアクセスする領域である.

1.同時に臨界領域に近づくことによる誤動作


  • 以前の銀行口座の問題です.childとparentが共通変数balanceに同時にアクセスすると、総残高は実際とは異なります.
    =>共通変数balanceの同時更新.
  • 上図では、balanceを更新する部分は臨界領域であり、各スレッドには臨界領域のコードがあるため、誤った結果が出力される可能性がある.
  • 2.臨界領域の問題を解決する方法

  • 反発:1つのスレッドにのみアクセスできます.コンテキスト切替が発生しても、臨界領域の1つのスレッドにしかアクセスできません.
  • Progress(実行):Threedが入るかどうかは、限られた時間内に決定されます.
  • Bounded待機(有限待機):任意のスレッドが有限時間で臨界領域に入ることができる.すなわち、待ち時間が限られている.
  • この3つが満たされてこそ,臨界領域問題を解決することができる.

    3.プロセス/スレッド同期


    :臨界領域の問題を解決するために、プロセスの実行順序を制御し、busy waitなどの低効率性を解消するために同期する必要があります.

    同期ツール

  • 信号量:細麻布語、従来の同期ツール
  • モニタ:Javaで使用するツール
  • mics
  • 4.信号量(細い麻布語)-反発処理



    細粒度:複数のExtraによって設計され、2つの原子関数によって動作する整数変数で、マルチプログラミング環境での共有リソースへのアクセスを制限します.これは相互反発を処理する方法である.
  • すなわち、細胞は整数型変数と2つの動作(P,V)からなる.
  • という2つの動作PとVは現代になって、Pは習得して、Vは釈放します.
  • は、信号量をjavaのシンボルとして以下に示す.
  • class Semaphore
    {
      int value = 1; //number of permits, 권한의 개수. 현재는 1.
      Semaphore(int value)
      {
    
      }
      void acquire()
      {
        value--;
        if (value < 0)
        {
          add this process/thread to list;//세마포어 안의 큐 리스트에 추가
          block;
        }
      }
      void release()
      {
        value++;
        if (value <= 0)
        {
          remove a process P from list;//세마포어 안의 큐 리스트에서 제거
          wakeup P;
        }
      }
    }
    上のコードを見ると、細い麻布にQが入っているのが見えます.このqueueを用いると,信号量が臨界領域にvalue個を超えるスレッドは存在しないことがわかる.

    <上記のコードと画像で信号量の実際の動作を理解しましょう>


    すべての臨界領域に近いコードは、臨界領域に近づく前に取得()を呼び出す.臨界領域にアクセスするコードが実行されるとrelease()が呼び出されます.
    コードの例を次に示します.
    acquire();
    balance = balance + n;//여기서 공통 변수는 balance. 임계 구역에 접근하는 코드
    release();

  • このように、臨界領域に近いコードがあれば、そのコードを実行する前に取得()を呼び出し、コード実行後にrelease()を呼び出す.

  • 呼び出し取得()の前の値が1の場合、呼び出し取得()の後、この値は1減少して0になりますが、取得()のif文の条件(値<0)を満たしていないため、臨界領域にアクセスするコードは安全に動作します(臨界領域に入ります).

  • ただし、release()の実行前にコンテキスト切替が発生し、別のスレッドに切り替えられたと仮定します.今回は、同じ変数にアクセスする臨界領域を持つコードが実行され、実行前に取得()も呼び出されます.

  • 現在の値は0で、取得()を呼び出したときの値は-1です.取得()のif文内の条件(value<0)を満たすため、スレッドは臨界領域にアクセスできず、信号量内部のキューを待つことができない.

  • 次のスレッドでrelease()が実行される場合、値は0で、release()内部のif文条件(value<=0)を満たします.したがって,信号量中のqueueにブロックされた2番スレッドはキューから脱出し,wakeup状態に入り,2番スレッドは臨界領域にアクセスできる.
  • ==>このようにして、信号量は、臨界領域にアクセスするスレッドの数を制限することができる.細麻布語により臨界領域問題を解決する方法の一つである反発問題を処理できる.