원자 조작

컴퓨터 과학에서 원자 조작(Atomic Operation, 原子操作)이라 함은 결합하여 외부에서는 하나의 조작으로 보이는 조작의 집합을 말한다. 원자 조작의 결과는 성공이나 실패 중의 하나이다.

조건 
이것이 가능하려면 다음 두가지 조건이 반드시 만족해야 한다.
 모든 조작이 완료할 때까지 어떤 프로세스도 변경을 알지 못하도록 비가시적이어야 하며
 조작중에 어느 하나라도 실패한다면 조작 전체도 실패하고 시스템의 상태를 조작 이전 상태로 복구해야 한다.

외부에서는 조작의 집합이 단번에 성공하거나 실패하는 것으로 보인다. 그 사이에 어정쩡한 상태가 없어야 한다. 이것이 원자 조작이다.

복수의 처리 장치가 있는 시스템처럼 복잡하지 않은 경우라도 이를 구현하는 것은 중요하다. 흐름 제어에서 변화의 가능성이 있는 한, 원자성 없이는 시스템이 바르지 못한 상태로 빠질 가능성이 있다.

예

프로세스가 하나인 경우 
예를 들면 컴퓨터에서 메모리의 특정 위치에서 값을 1씩 증가시키는 프로세스가 있다고 하자. 메모리의 값을 1씩 증가시키는 절차는 다음과 같다.
 프로세스는 메모리의 특정 위치에서 값을 읽어온다.
 프로세스는 그값에 1을 더한다.
 프로세스는 새로 계산한 값을 메모리의 원래 위치에 써넣는다.

프로세스가 둘인 경우 
이번에는 실행중인 두 프로세스가 공유하는 메모리의 위치에서 값을 1씩 증가시킨다고 생각해 보자.
 첫째 프로세스는 메모리의 특정 위치에서 값을 읽어온다.
 첫째 프로세스는 그값에 1을 더한다. 
그런데 첫째 프로세스가 계산한 값을 원래 위치에 써넣으려던 순간 실행권을 박탈 당하고 둘째 프로세스가 실행된다.
 둘째 프로세스는 메모리의 특정 위치에서 첫째 프로세스가 읽은 동일한 값을 읽어온다.
 둘째 프로세스는 그값에 1을 더한다.
 둘째 프로세스는 계산한 새 값을 메모리의 원래 위치에 써넣는다.
둘째 프로세스의 실행이 정지되고 다시 첫째 프로세스의 차례가 돌아온다.
 첫째 프로세스는 다른 프로세스가 값을 변경한 사실을 모른 채 잘못된 값을 메모리에 써넣는다.

이것은 간단한 예이다. 실제 시스템에서는 조작이 보다 복잡하며 극히 미묘한 오류가 발생할 수도 있다. 예를 들면 메모리에서 64비트를 읽어오는 조작이 실제로는 32비트를 연속으로 두 번 읽어오는 조작일 수도 있다. 프로세스가 처음 32비트만 읽고 나중 32비트를 아직 읽어오지 못한 상태에서 값이 변경되면, 원래 값도 아니고 새로운 값도 아닌 무의미한 값을 읽게 된다.

더욱이 프로세스간의 실행 순서에 따라서도 결과가 달라지므로 이러한 오류는 찾아서 수정하기가 매우 어렵다.

락 
이러한 문제는 공유하는 "임계 구역"(Critical Section)에 락(Lock)을 걸어서 해결할 수 있다. 프로세서의 하드웨어적인 도움없이 락을 구현한다면 락은 읽고 검사하고 써야 할 메모리상의 한 위치에 지나지 않는다. 스핀락과 같이 소프트웨어만으로 구현한 알고리즘도 있으나 이들로써는 비효율적이다.

트랜잭션 처리
동시성 제어