(운영체제) Atomic Operation이란?
*Atomic Operation의 사전적 의미.
기능적으로 분할할 수 없거나 분할되지 않도록 보증된 조작. 원자와 같이 분할할 수 없다는 것을 비유하여 원자조작은 끼어들기가 불가능하며, 만일 중지되면 동작 개시 직전의 상태로 시스템을 복귀시킬 것을 보증하는 복구(백업과 복원)기능이 제공된다.
*Atomic Operation의 프로그래밍 언어적 의미
Atomic Operation이 필요한 부분은 멀티스레드 프로그램에서 공유자원들에 대해 여러 스레드가 동시에 액세스하는 경쟁상태(race condition)을 막기 위한 하나의 방법이다.
쉽게 말해 동기화를 위한 하나의 방법이다.
이것이 가능하려면 다음 두가지 조건이 반드시 만족해야 한다.
1. 모든 조작이 완료할 때 까지 어떤 프로세스도 변경을 알지 못하도록 비가시적이어야 하며
2. 조작중에 어느 하나라도 실패한다면 조작 전체도 실패하고 시스템의 상태를 조작 이전의 상태로 복구해야 한다.
외부에서는 조작의 집합이 단번에 성공하거나 실패하는 것으로 보인다. 그 사이에 어정쩡한 상태가 없어야 한다. 이것이 원자조작이다. 복수의 처리 장치가 있는 시스템처럼 복잡하지 않는 경우라도 이를 구현하는 것은 중요하다. 흐름제어의 변호의 가능성이 있는 한 원자성 없이는 시스템이 바르지 못한 상태로 빠질 가능성이 있다.
-프로세스가 하나인 경우
예를들면 컴퓨터에서 메모리의 특정 위치에서 값을 1씩 증가시키는 프로세스가 있다고 치자. 메모리의 값을 1씩 증가시키는 절차는 다음과 같다.
-프로세스가 둘인 경우
이번에는 실행중인 두 프로세스가 공유하는 메모리의 위치에서 값을 1씩 증가시킨다고 해보자.
1. 첫째 프로세스는 메모리의 특정 위치에서 값을 읽어온다.
2. 첫째 프로세스는 그 값에 1을 더한다.
그런데 첫째 프로세스가 계산한 값을 원래 위치에 써넣으려던 순간 실행권을 박탈당하고 두번째 프로세스가 실행된다.
1. 둘쨰 프로세스는 메모리의 특정위치에서 첫쨰 프로세스가 읽은 동일한 값을 읽어온다.
2. 둘째 프로세슨ㄴ 그 값에 1을 더한다.
3. 둘째 프로세스는 계산한 새 값을 메모리의 원래 위치에 써넣는다.
둘쨰 프로세스의 실행이 정지되고 다시 첫째 프로세스의 차례가 돌아온다.
1. 첫째 프로세스는 다른 프로세스가 값을 변경한 사실을 모른채 잘못된 값을 메모리에 써넣는다.
기능적으로 분할할 수 없거나 분할되지 않도록 보증된 조작. 원자와 같이 분할할 수 없다는 것을 비유하여 원자조작은 끼어들기가 불가능하며, 만일 중지되면 동작 개시 직전의 상태로 시스템을 복귀시킬 것을 보증하는 복구(백업과 복원)기능이 제공된다.
*Atomic Operation의 프로그래밍 언어적 의미
Atomic Operation이 필요한 부분은 멀티스레드 프로그램에서 공유자원들에 대해 여러 스레드가 동시에 액세스하는 경쟁상태(race condition)을 막기 위한 하나의 방법이다.
쉽게 말해 동기화를 위한 하나의 방법이다.
이것이 가능하려면 다음 두가지 조건이 반드시 만족해야 한다.
1. 모든 조작이 완료할 때 까지 어떤 프로세스도 변경을 알지 못하도록 비가시적이어야 하며
2. 조작중에 어느 하나라도 실패한다면 조작 전체도 실패하고 시스템의 상태를 조작 이전의 상태로 복구해야 한다.
외부에서는 조작의 집합이 단번에 성공하거나 실패하는 것으로 보인다. 그 사이에 어정쩡한 상태가 없어야 한다. 이것이 원자조작이다. 복수의 처리 장치가 있는 시스템처럼 복잡하지 않는 경우라도 이를 구현하는 것은 중요하다. 흐름제어의 변호의 가능성이 있는 한 원자성 없이는 시스템이 바르지 못한 상태로 빠질 가능성이 있다.
-프로세스가 하나인 경우
예를들면 컴퓨터에서 메모리의 특정 위치에서 값을 1씩 증가시키는 프로세스가 있다고 치자. 메모리의 값을 1씩 증가시키는 절차는 다음과 같다.
- 프로세스는 메모리의 특정 위치에서 값을 읽어온다.
- 프로세스는 그 값에 1을 더한다.
-프로세스가 둘인 경우
이번에는 실행중인 두 프로세스가 공유하는 메모리의 위치에서 값을 1씩 증가시킨다고 해보자.
1. 첫째 프로세스는 메모리의 특정 위치에서 값을 읽어온다.
2. 첫째 프로세스는 그 값에 1을 더한다.
그런데 첫째 프로세스가 계산한 값을 원래 위치에 써넣으려던 순간 실행권을 박탈당하고 두번째 프로세스가 실행된다.
1. 둘쨰 프로세스는 메모리의 특정위치에서 첫쨰 프로세스가 읽은 동일한 값을 읽어온다.
2. 둘째 프로세슨ㄴ 그 값에 1을 더한다.
3. 둘째 프로세스는 계산한 새 값을 메모리의 원래 위치에 써넣는다.
둘쨰 프로세스의 실행이 정지되고 다시 첫째 프로세스의 차례가 돌아온다.
1. 첫째 프로세스는 다른 프로세스가 값을 변경한 사실을 모른채 잘못된 값을 메모리에 써넣는다.
이것은 간단한 예이다. 실제 시스템에서는 조작이 보다 복잡하며 극히 미묘한 오류가 발생할 수도 있다. 예를 들면 메모리에서 64비트를 읽어오는 조작이 실제로는 32비트를 연속으로 두 번 읽어오는 조작일 수도 있다. 프로세스가 처음 32비트만 읽고 나중 32비트를 아직 읽어오지 못한 상태에서 값이 변경되면, 원래 값도 아니고 새로운 값도 아닌 무의미한 값을 읽게 된다.
더욱이 프로세스간의 실행 순서에 따라서도 결과가 달라지므로 이러한 오류는 찾아서 수정하기가 매우 어렵다.
---------------------------------------------------------------
동기화에 대해 간단히 정리하면
윈도우 프로그램에서는 동기화는 커널모드 동기화, 유저모드 동기화 두개로 구분되고,
이 중에서 유저모드는 Atomic Operation과 CRITICAL_SECTION으로 구분되고, 커널모드는 세마포어와 뮤텍스로 구분된다.
다시 유저모드를 보면 Atomic Operation이라는 말 보다는 Interlocked계열 함수로 많이 얘기하는 방법과 CRITICAL_SECTION이 있다. 이 두가지 방법은 유저모드의 동기화 기법답게 커널모드 동기화에 비해 동기화에 사용되는 비용이 훨씩적다(빠르다)는 장점을 지니고 있다.
이중에서도 Interlocked계열 함수들의 경우 간단한 하나의 변수에 대한 동기화 처리에 대해 많이 이용된다.
요즘 Interlocked계열 함수가 Atomic Operation으로 멀티스레드에 대해 안전성을 보장하느냐에 대해 의견들이 많은데,
최근에 개발된 대부분의 CPU에서는 Atomic Operation을 지원하고, 내부적으로는 윈도우가 지원하는 Lock도 이런한 CPU의 Atomic Operation을 사용하기 때문에 멀티스레드에 대한 안정성을 보장한다고 본다.
지금까지 별 의심 않고 사용해 온 Interlocked께열 함수들을 앞으로도 쭉 그냥 써도 무방하다는 얘기 이다.
댓글
댓글 쓰기