Ada의 동시성 지원
잠그는 코드를 한 줄도 쓰지 않고 한 번에 하나만 들여보낼 수 있을까?
태스크 명세부
받을 메시지를 창구로 알립니다
Ada의 태스크는 명세부와 본체부로 나뉩니다. 명세부에는 바깥에서 메시지를 보낼 수 있는 창구인 엔트리(entry)를 적습니다. 다른 태스크는 엔트리의 이름으로 메시지를 보냅니다.
읽는 법: task 이름 is부터 end 이름;까지가 명세부입니다. Item : in Integer는 정수 하나를 받는다는 뜻입니다.
accept 절
accept에서 만납니다
본체부에는 엔트리마다 accept 절을 둡니다. 태스크는 accept에 이르면 메시지를 기다리고, 메시지가 오면 do와 end 사이를 실행합니다. 그동안 보낸 쪽은 멈춰 있습니다. 이 구간이 6편의 랑데부입니다.
랑데부는 두 태스크가 만나 메시지가 건너가는 것입니다. 점선은 기다리는 구간입니다.
경쟁 동기화
한 번에 accept 하나뿐이라서
공유 버퍼와 그 연산을 태스크 하나에 넣어 둡니다. 한 태스크 안에서는 한 번에 accept 절 하나만 실행되므로 메시지는 하나씩만 처리됩니다. 잠그는 코드를 쓰지 않아도 3편의 상호 배제가 됩니다.
아직 받아들여지지 않은 메시지는 그 accept 절의 큐에서 기다립니다.
select
와 있는 쪽을 받습니다
엔트리가 여럿이면 accept 절들을 select에 넣습니다. 메시지가 와 있는 큐에서 하나를 받고, 모두 비었으면 기다립니다. 이것이 선택적 대기(selective wait)입니다.
Teller는 은행 창구 직원입니다. Drive_Up은 차를 탄 손님, Walk_Up은 걸어온 손님의 엔트리입니다.
협력 동기화
조건이 맞을 때만 엽니다
accept 절 앞에 when으로 조건을 달 수 있습니다. 이 조건이 가드(guard)입니다. 가드가 참이면 열린 절이라 메시지를 받고, 거짓이면 닫힌 절이라 받지 않습니다.
읽는 법: when 조건 => 는 조건이 참일 때만 아래 accept를 연다는 뜻입니다. not Full(Buffer)는 버퍼가 꽉 차지 않았다는 조건입니다.
보호 객체
읽기만 하면 함께 들어갑니다
Ada 95는 보호 객체(protected object)를 더했습니다. 랑데부 없이 공유 데이터를 쓰는 더 효율적인 길입니다. 값을 바꾸는 보호 프로시저는 한 번에 하나만, 읽기만 하는 보호 함수는 여럿이 함께 실행됩니다.
프로시저와 함수는 둘 다 서브프로그램입니다. 여기서는 값을 바꾸면 프로시저, 읽기만 하면 함수로 가릅니다.
Ada 평가
떨어진 컴퓨터끼리는 메시지로
한 컴퓨터 안에서라면 모니터와 메시지 전달 가운데 어느 쪽이든 좋습니다. 하지만 컴퓨터가 여러 대로 흩어진 분산 시스템에서는 메모리를 함께 쓸 수 없으므로 메시지 전달이 더 낫습니다.
지금까지 본 공유 변수와 공유 데이터는 한 메모리를 함께 쓴다는 것을 전제로 했습니다.
다음 편