Unix C 에서 atomic operation 단위가 무엇인가요?

dobi2000의 이미지

보통 멀티 쓰레드 프로그래밍이나 멀티 프로세스에서 하나의 파일을 억세스해서 읽고 쓰기를 할 때 OS 레벨에서 (다른 프로세스/쓰레드에 영향을 받지 않고) 원자성을 보장받을 수 있는 단위가 무엇인지 궁금합니다. (CPU 인스트럭션 단위인가요? -_-)

단적인 예를 들어 하나의 파일을 여러개의 쓰레드 (혹은 프로세스)가 오픈을 해서 동시에 특정 정보를 쓰기를 시도할 때 썪이지(?) 않고 잘 쓰여질 수 있는지요. 물론 fprintf 이후에 flush를 바로 하거나 write 함수를 쓴다는 가정입니다.

제가 아는 어설픈 지식은 UNIX C 상에서 하나의 시스템 콜이나 한 줄의 문장이 OS 레벨에서 완전하게 처리가 끝나지 않더라도 다른 쓰레드가 스케줄링이 될 수도 있다는 것으로 알고 있습니다. 혹시 write 함수가 atomic operation 보장을 받지는 못하더라도 시스템 내부의 읽고 쓰기의 한 블럭 (크기는 정해졌겠지만) 단위 만큼은 보장을 받을 수 있는지도 궁금합니다.

질문의 두서가 없지만, 고수님들께서는 제 질문의 의미를 파악하셨으리라 믿고 미리 감사의 말씀 드립니다. 감사합니다.

익명 사용자의 이미지

dobi2000 wrote:

....

일반적으로 원자성을 보장할 수 없다는 견해입니다.
운영체제의 구현에 따라 틀려질 것이고, 예를 든것 또한 운영체제별로 보장할 수도 아닐수도 있다고 생각합니다.

* 정설은 아니며, 제 개인적인 견해입니다.
* 참고로, Dijkstra의 THE 라는 OS는 한 페이지에 대해서는 atomic operation을 보장했다고 합니다.

익명 사용자의 이미지

semaphore또는 유사한 ipc를 이용하는 것 외에 atomic한걸 보장하는 방법 없습니다.

무우의 이미지

리눅스에서는 되는 걸로 알고 있습니다..
<asm/atomic.h> 를 참고하세요.

ed.netdiver의 이미지

헉, IPC가 atomic을 보장하나요?
atomic하단건 scheduling되지 않는다는 뜻으로 알고있었습니다만...

--------------------------------------------------------------------------------
\(´∇`)ノ \(´∇`)ノ \(´∇`)ノ \(´∇`)ノ
def ed():neTdiVeR in range(thEeArTh)

익명 사용자의 이미지

qed wrote:
헉, IPC가 atomic을 보장하나요?
atomic하단건 scheduling되지 않는다는 뜻으로 알고있었습니다만...

mutual exclusion이 보장되는 것이라고 보면 맞겠습니다.
당연히, 다른 프로세스/쓰레드에게 해당 자원이 배당(리소스 스케쥴)되어서는 아니될것입니다.
(다른)손님의 말씀은 아마도, IPC를 이용해서 atomic 연산을 구현한다는 의미인것같습니다.
익명 사용자의 이미지

무우 wrote:
리눅스에서는 되는 걸로 알고 있습니다..
<asm/atomic.h> 를 참고하세요.

리눅스라고 되는것은 아닙니다.
단지, atomic 연산을 위한 프리미티브에 대한 예라고 볼 정도입니다. 이를 확장해서, 특정 시스템호출을 atomic하게 구현할 수는 있겠지요.
binul의 이미지

RTOS인 MicroC/OS의 코드를 살펴보면 16비트로 포팅된다고 가정할 때 16비트 변수를 증가시키는 것과 같은 코드, 예를 들어
v16++
과 같은 코드는 atomic하게 보는 거 같더군요.
위의 코드가 machine code로 어떻게 나올지는 모르겠습니다.
(한 instruction으로 끝나지는 않을 것 같은데...)

그리고 당연하게, 32비트 변수의 경우에는

DisableInterrupt();
v32++;
EnableInterrupt();

와 같이...

흙, 고수가 아니라서 주제에서 벗어나 버린듯한 이 느낌; :oops:

--------------------------------
그래날아보자꾸나

ed.netdiver의 이미지

Anonymous wrote:
qed wrote:
헉, IPC가 atomic을 보장하나요?
atomic하단건 scheduling되지 않는다는 뜻으로 알고있었습니다만...

mutual exclusion이 보장되는 것이라고 보면 맞겠습니다.
당연히, 다른 프로세스/쓰레드에게 해당 자원이 배당(리소스 스케쥴)되어서는 아니될것입니다.
(다른)손님의 말씀은 아마도, IPC를 이용해서 atomic 연산을 구현한다는 의미인것같습니다.

하지만 상호배제는 resource 혹은 routine의 독점적 점유권(상호 쟁탈상황시)을 보장하는 mechanism이지 scheduler의 고유권한(context switching)자체를 block하는 것은 아니지 않나요?

--------------------------------------------------------------------------------
\(´∇`)ノ \(´∇`)ノ \(´∇`)ノ \(´∇`)ノ
def ed():neTdiVeR in range(thEeArTh)

binul의 이미지

qed wrote:
Anonymous wrote:
qed wrote:
헉, IPC가 atomic을 보장하나요?
atomic하단건 scheduling되지 않는다는 뜻으로 알고있었습니다만...

mutual exclusion이 보장되는 것이라고 보면 맞겠습니다.
당연히, 다른 프로세스/쓰레드에게 해당 자원이 배당(리소스 스케쥴)되어서는 아니될것입니다.
(다른)손님의 말씀은 아마도, IPC를 이용해서 atomic 연산을 구현한다는 의미인것같습니다.

하지만 상호배제는 resource 혹은 routine의 독점적 점유권(상호 쟁탈상황시)을 보장하는 mechanism이지 scheduler의 고유권한(context switching)자체를 block하는 것은 아니지 않나요?

의미적으론 qed님의 말씀이 맞습니다. 하지만, mutual exclusion을 보장하기 위해서 interrupt가 disable되며, 이를 통해 context switching은 일어나지 않는 것으로 알고 있습니다.

--------------------------------
그래날아보자꾸나

spacelee의 이미지

=> 시스템 내부의 읽고 쓰기의 한 블럭 (크기는 정해졌겠지만) 단위 만큼은 보장을 받을 수 있는지도 궁금합니다.

저도 몇년 전에 고민을 했던 부분인데
정확히 기억은 나지 않지만,
문서들을 찾았거나 혹은 테스트를 해본 결과
위 말씀이 95%는 맞는 것 같습니다. ^^

안되는 5%는
한번의 write가 파일의 블럭 단위 경계에
걸쳐있을 경우 같습니다.
그때는 보장이 안되었던것 같습니다.
그리고 OS마다 dependacy가 있었던거 같기도 하구요.
솔직히 오래되서 정확히는 기억이 나지 않습니다..^^;;

어쨌든 OS 마다 동작이 다를 수도 있고
버퍼링으로 인한 속도 문제도 있고해서
FILE 같은 객체를 직접 만들어 썼습니다.

mutex 와 내부 버퍼를 이용했구요. (유닉스)
로직은 간단하니깐 만드는 것은 어렵지 않으실꺼구요.

버퍼까지 필요없다면,
원자성을 보장하기 위해서
파일 오퍼레이션을 mutex와 descriptor로
간단하게 한번 wrapping한 객체를
만들어 쓰셔도 될듯합니다.

원자성에 대해서는
어렴풋이 아시는 것처럼
i++;
이런 문장도 원자성이 보장되지 않습니다.^^
왜냐면 이 문장은 내부적으로
메모리의 i값 -> 레지스터
레지스터에서 ++ 연산
레지스터 값 - >메모리 i 위치

이렇게 세 단계의 어셈블러 코드를 거치기 때문이죠.
이 중간 어디서 스케줄링이 다른 쓰레드로 넘어갈지
모릅니다.

권위를 의심할 것,어긋남을 존경할 것,자리잡기를 거부할 것,항상 자신을 재창조할 것 - MIT 미디어랩 -

익명 사용자의 이미지

atomic연산을 생각할때는 데이터베이스의 트랜잭션을 생각하는게 도움이 됩니다.
i++또는 인터럽트와 같이 아주 작은 단위의 연산을 고려할 수 있겠습니다만, 스케일을 올려서 생각하면 보다 이해가 쉬울듯 합니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.