최근 포토로그


APC에 대하여 복잡한컴퓨터이야기

정말 간만에 vc newsgroup에 돌아왔습니다.

APC 는 asynchronous procedure call 의 약자입니다.

그렇다면 synchronous procedure call(이하 SPC 라고 합시다)는 무엇일까요?

SPC는 일반적으로 우리하 호출하는 함수입니다. 즉 함수의 이름과 parameter를 전달하면

stack을 이용하여 parameter를 push하고 instruction pointer를 호출한 함수로 이동하게 되겠지요.

뭐 일반적인 함수의 호출방식이니 이에 대한 문의는 없을 것 같구용.



APC는 참으로 특이한 녀석입니다. 하나씩 알아보지용

SPC에서는 호출되는 함수의 signature를 정의하는 방법이 특별히 제한되어 있지는 않지만

APC를 사용하기 위해서는 항상 다음과 같은 형태를 띄어야 합니다.



VOID CALLBACK APCProc(ULONG_PTR dwParam);



이 signature를 보면 parameter가 pointer 변수하나를 받기 때문에,

이걸 잘 활용하면 어떤 갯수의 어떤 data든 보낼 수 있습니다.



그럼 이 함수를 어떻게 호출할까요? CALLBACK 으로 정의되어 있으니,

함수이름을 써서 우리가 직접호출하지는 않을것을 예측할 수 있습니다.



이러한 APC procedure를 호출하는 방법이 바로 QueueUserAPC() 를 사용하시면 됩니다.



Signature를 보면



DWORD QueueUserAPC(

PAPCFUNC pfnAPC,

HANDLE hThread,

ULONG_PTR dwData

);



첫번째 parameter는 APC procedure의 function pointer를 써주면 됩니다.

세번째 parameter는 APC procedure의 parameter로 넘겨줄 값을 쓰면됩니다.

두번째 parameter는 실제로 사용자가 정의한 APC procedure를 어떤 thread가 호출하게 하겠느냐 입니다.



그런데 여기서 또 한가지를 더 알아야 합니다.

우리가 QueueUserAPC()에 적절히 값을 넣어서 호출한다고 해서 APC procedure가 지정한 thread에 의해서

지정한 parameter를 가지고 바로 호출되는 것이 아닙니다.

그럼 언제 호출되는고 하니 사용자가 지정한 thread 가 alertable 상태가 될 때 호출됩니다.

그렇다면 alertable 상태란건 무엇일까요?



windows의 thread 들은 그 thread가 생성되어 파괴될때 까지 자신의 상태를 가지고 있습니다.

"Waiting" 상태는 thread가 특정 event를 받기 이전까지는 아무것도 하지 않는 상태입니다.

이 상태는 사용자가 WaitFor.. 류의 wait function 또는 Sleep류의 함수를 사용하면 thread는 이 상태로 진입하게 됩니다.

이 경우 CPU scheduling 대상에서 이 thread는 제외됩니다.



"Ready" 상태는 CPU scheduing 대상이긴 하나 아직 CPU 의 quantium time을 받지 못한 상태를 말합니다.

이 경우 CPU time만 받으면 바로 실행 상태로 변경되겠지요



"Running" 상태는 CPU가 현재 이 thread를 수행하고 있는 상태를 말합니다.

Thread가 수행되고 있다는 것은 "Ready" 상태와 "Running" 상태를 오가면서 code가 수행되는 것을 말하겠지요



그런데,, 쿠쿵, 제4의 상태가 있습니다. 그게 바로 alertable 상태입니다.



위에서 설명한 3가지의 상태는 Windows가 직접적으로 관할을 하지요.

예를들어 Waiting 상태에서 event를 기다리는 thread는 특정 event가 발생했을때 windows가

직접적으로 Ready 상태로 변경을 해주고, 또한 ready 상태에서 Scheduler에 의해서 CPU Time을

받게 되면 Running 상태로 진입하게 됩니다.



하지만 alertable 상태는 사용자가 조정할 수 있는 유일한 thread의 상태입니다.

alertable state로 thread의 상태를 변경하는 방법은 WaitFor...Ex 류의 함수를 사용하면 됩니다.

또는 SleepEx 와 같은 함수도 가능합니다. 가장 간단한 SleepEx를 봅시다



DWORD SleepEx(

DWORD dwMilliseconds,

BOOL bAlertable

)



이 함수를 호출하게 되면, Thread는 Waiting 상태로 진입하여, 지정한 시간이 지날때 까지 깨어나지 않고 기다립니다

그런데 만일 두번째 parameter로 TRUE를 전달하게 되면, Thread는 그 유명한 alertable 상태로 진입을 하게됩니다.

alertable 상태로 진입한 thread는 APCQueue라고 불리우는 Queue에 혹시 Queueing 된 정보가 있는지

확인을 하게 됩니다. Queueing된 정보란 QueueUserAPC() 함수에 의해서 전달된

3가지 정보가 하나의 node가 되겠지요, Thread는 Queue로부터 하나의 node를 빼와서

지정한 함수를 호출하는 것입니다.



만일 APC Queue에 Queueing된 node가 10개정도 되고, SleepEx에서 1초정도를 대기시간으로 했다고 가정합시다.

물론 bAlertable을 TRUE로 주었다고 가정하지요.



이 경우 Thread는 1초동안 Alertable 상태이기 때문에, APC Queue로 부터 node를 가져다가

지정된 함수를 호출하여 수행을 계속해갈 것입니다.

그런데 3번째 node를 수행하는 중에, 1초가 되어버렸습니다.

이경우 3번째 node까지만을 수행하고, Thread는 event를 받아 ready 상태로 진입하게 됩니다.



이해가 되셨는지요?

그럼 도움이 되셨길...





"공부합시당..." <@discussions.microsoft.com> wrote in message news:A76CA6D8-7072-444C-8F66-47C4D3DFE171@microsoft.com...

> APC 가 뭐죠?...
>
> QueueUserAPC 가 이것과 관련이 있다고 보여집니다만...
>
> 각각의 스레드는 APC 큐라는 게 있다고 하는 군요.
>
> 약간의 개념이라도 설명을 부탁드립니다.


핑백

덧글

  • 박상 2005/07/02 13:40 # 답글

    APC에 대해서는 알고는 있었지만,
    QueueUserAPC라는 함수와 함께 더 잘 정리가 되네요.
    감사합니다. ^^
  • 김명신 2005/07/04 13:39 # 답글

    넹 감사합니다. microsoft.public.kr.vc.qna 에 와서 많은 분들과 정보를 공유하시면 좋겠습니다.
  • 미친병아리 2005/09/18 01:18 # 답글

    즐거운 추석 연휴 보내세요~
  • 김영주 2008/01/24 02:40 # 삭제 답글

    좋은자료 감사합니다.
  • 최익필 2008/12/28 18:04 # 삭제 답글

    오, 좋은 글이였습니다. 감사합니다.
  • 김영균 2011/02/16 15:54 # 삭제 답글

    멋진 글이네요... 책에서 볼때는 햇갈렸던 개념을
    알기쉽게 말씀해 주셔서 감사 드려요 ^^
  • 오곡 2013/12/01 21:37 # 삭제 답글

    잘배우고 갑니다~
  • 7 2015/03/19 18:20 # 삭제 답글

    검색하다 우연찮게 들렸는데 정말 명쾌한 설명이시네요. 잘 보고 갑니다
  • 김명신 2015/03/30 22:35 #

    10년전에 쓴글인데.. 도움이 되셨다니 다행입니다.
  • 2018/02/22 14:36 # 삭제 답글

    진짜 너무 좋은 글이었습니다. 감사합니다..........감격
댓글 입력 영역


facebook 프로필 위젯

트위터 위젯