Unix C 에서 atomic operation 단위가 무엇인가요?
글쓴이: dobi2000 / 작성시간: 월, 2005/08/01 - 2:16오후
보통 멀티 쓰레드 프로그래밍이나 멀티 프로세스에서 하나의 파일을 억세스해서 읽고 쓰기를 할 때 OS 레벨에서 (다른 프로세스/쓰레드에 영향을 받지 않고) 원자성을 보장받을 수 있는 단위가 무엇인지 궁금합니다. (CPU 인스트럭션 단위인가요? -_-)
단적인 예를 들어 하나의 파일을 여러개의 쓰레드 (혹은 프로세스)가 오픈을 해서 동시에 특정 정보를 쓰기를 시도할 때 썪이지(?) 않고 잘 쓰여질 수 있는지요. 물론 fprintf 이후에 flush를 바로 하거나 write 함수를 쓴다는 가정입니다.
제가 아는 어설픈 지식은 UNIX C 상에서 하나의 시스템 콜이나 한 줄의 문장이 OS 레벨에서 완전하게 처리가 끝나지 않더라도 다른 쓰레드가 스케줄링이 될 수도 있다는 것으로 알고 있습니다. 혹시 write 함수가 atomic operation 보장을 받지는 못하더라도 시스템 내부의 읽고 쓰기의 한 블럭 (크기는 정해졌겠지만) 단위 만큼은 보장을 받을 수 있는지도 궁금합니다.
질문의 두서가 없지만, 고수님들께서는 제 질문의 의미를 파악하셨으리라 믿고 미리 감사의 말씀 드립니다. 감사합니다.
Forums:
Re: Unix C 에서 atomic operation 단위가 무엇인가요?
일반적으로 원자성을 보장할 수 없다는 견해입니다.
운영체제의 구현에 따라 틀려질 것이고, 예를 든것 또한 운영체제별로 보장할 수도 아닐수도 있다고 생각합니다.
* 정설은 아니며, 제 개인적인 견해입니다.
* 참고로, Dijkstra의 THE 라는 OS는 한 페이지에 대해서는 atomic operation을 보장했다고 합니다.
semaphore또는 유사한 ipc를 이용하는 것 외에 atomic한걸
semaphore또는 유사한 ipc를 이용하는 것 외에 atomic한걸 보장하는 방법 없습니다.
리눅스에서는 되는 걸로 알고 있습니다..<asm/atomic.h
리눅스에서는 되는 걸로 알고 있습니다..
<asm/atomic.h> 를 참고하세요.
헉, IPC가 atomic을 보장하나요?atomic하단건 schedu
헉, IPC가 atomic을 보장하나요?
atomic하단건 scheduling되지 않는다는 뜻으로 알고있었습니다만...
--------------------------------------------------------------------------------
\(´∇`)ノ \(´∇`)ノ \(´∇`)ノ \(´∇`)ノ
def ed():neTdiVeR in range(thEeArTh)
[quote="qed"]헉, IPC가 atomic을 보장하나요?ato
mutual exclusion이 보장되는 것이라고 보면 맞겠습니다.
당연히, 다른 프로세스/쓰레드에게 해당 자원이 배당(리소스 스케쥴)되어서는 아니될것입니다.
(다른)손님의 말씀은 아마도, IPC를 이용해서 atomic 연산을 구현한다는 의미인것같습니다.
[quote="무우"]리눅스에서는 되는 걸로 알고 있습니다..<
리눅스라고 되는것은 아닙니다.
단지, atomic 연산을 위한 프리미티브에 대한 예라고 볼 정도입니다. 이를 확장해서, 특정 시스템호출을 atomic하게 구현할 수는 있겠지요.
RTOS인 MicroC/OS의 코드를 살펴보면 16비트로 포팅된다고 가정
RTOS인 MicroC/OS의 코드를 살펴보면 16비트로 포팅된다고 가정할 때 16비트 변수를 증가시키는 것과 같은 코드, 예를 들어
v16++
과 같은 코드는 atomic하게 보는 거 같더군요.
위의 코드가 machine code로 어떻게 나올지는 모르겠습니다.
(한 instruction으로 끝나지는 않을 것 같은데...)
그리고 당연하게, 32비트 변수의 경우에는
와 같이...
흙, 고수가 아니라서 주제에서 벗어나 버린듯한 이 느낌; :oops:
--------------------------------
그래날아보자꾸나
[quote="Anonymous"][quote="qed"]헉, IPC가
하지만 상호배제는 resource 혹은 routine의 독점적 점유권(상호 쟁탈상황시)을 보장하는 mechanism이지 scheduler의 고유권한(context switching)자체를 block하는 것은 아니지 않나요?
--------------------------------------------------------------------------------
\(´∇`)ノ \(´∇`)ノ \(´∇`)ノ \(´∇`)ノ
def ed():neTdiVeR in range(thEeArTh)
[quote="qed"][quote="Anonymous"][quote="
의미적으론 qed님의 말씀이 맞습니다. 하지만, mutual exclusion을 보장하기 위해서 interrupt가 disable되며, 이를 통해 context switching은 일어나지 않는 것으로 알고 있습니다.
--------------------------------
그래날아보자꾸나
=> 시스템 내부의 읽고 쓰기의 한 블럭 (크기는 정해졌겠지만) 단
=> 시스템 내부의 읽고 쓰기의 한 블럭 (크기는 정해졌겠지만) 단위 만큼은 보장을 받을 수 있는지도 궁금합니다.
저도 몇년 전에 고민을 했던 부분인데
정확히 기억은 나지 않지만,
문서들을 찾았거나 혹은 테스트를 해본 결과
위 말씀이 95%는 맞는 것 같습니다. ^^
안되는 5%는
한번의 write가 파일의 블럭 단위 경계에
걸쳐있을 경우 같습니다.
그때는 보장이 안되었던것 같습니다.
그리고 OS마다 dependacy가 있었던거 같기도 하구요.
솔직히 오래되서 정확히는 기억이 나지 않습니다..^^;;
어쨌든 OS 마다 동작이 다를 수도 있고
버퍼링으로 인한 속도 문제도 있고해서
FILE 같은 객체를 직접 만들어 썼습니다.
mutex 와 내부 버퍼를 이용했구요. (유닉스)
로직은 간단하니깐 만드는 것은 어렵지 않으실꺼구요.
버퍼까지 필요없다면,
원자성을 보장하기 위해서
파일 오퍼레이션을 mutex와 descriptor로
간단하게 한번 wrapping한 객체를
만들어 쓰셔도 될듯합니다.
원자성에 대해서는
어렴풋이 아시는 것처럼
i++;
이런 문장도 원자성이 보장되지 않습니다.^^
왜냐면 이 문장은 내부적으로
메모리의 i값 -> 레지스터
레지스터에서 ++ 연산
레지스터 값 - >메모리 i 위치
이렇게 세 단계의 어셈블러 코드를 거치기 때문이죠.
이 중간 어디서 스케줄링이 다른 쓰레드로 넘어갈지
모릅니다.
권위를 의심할 것,어긋남을 존경할 것,자리잡기를 거부할 것,항상 자신을 재창조할 것 - MIT 미디어랩 -
atomic연산을 생각할때는 데이터베이스의 트랜잭션을 생각하는게 도움이
atomic연산을 생각할때는 데이터베이스의 트랜잭션을 생각하는게 도움이 됩니다.
i++또는 인터럽트와 같이 아주 작은 단위의 연산을 고려할 수 있겠습니다만, 스케일을 올려서 생각하면 보다 이해가 쉬울듯 합니다.
댓글 달기