Admin | Write | GuestBook
[공지] 해당 블로그에 용건이 있으신 분께서는 http://blog.fore.kr/ 의 방명록(Guestbook)으로 부탁드립니다.
심심하니, 쓰레드에 대해 이야기해보자.
Category : Programming/Programming Talk | URL : | Written by 포레 ( 2012. 10. 10. 14:52 ) | 신고

 

[번뜩 !]

 

진짜 할거없네 . . . 쓰레드에 대해 이야기해보자.

 

주제는 크게 지역변수와 쓰레드와의 관계이다.

 

쓰레드는 한 프로세스에 여러일을 동시에 해주는거처럼 보이게하는 아주 편리한 역활을 하고 있다.

 

이 편리한 쓰레드는 윈도우상 크게 쓰래드 함수가 2가지 종류로 존재한다.

 

 

 < CRT(C-RunTime) 함수 >

 

 uintptr_t _beginthread( 
   void( *start_address )( void * ),
   unsigned stack_size,
   void *arglist 
 );

 uintptr_t _beginthreadex( 
   void *security,
   unsigned stack_size,
   unsigned ( *start_address )( void * ),
   void *arglist,
   unsigned initflag,
   unsigned *thrdaddr
 );

 

 < 출처 >

 http://msdn.microsoft.com/en-us/library/kdzttdcb(v=VS.80).aspx

 

 

 

 < WIndows API 함수 >

 

 HANDLE WINAPI CreateThread(
  _In_opt_   LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_       SIZE_T dwStackSize,
  _In_       LPTHREAD_START_ROUTINE lpStartAddress,
  _In_opt_   LPVOID lpParameter,
  _In_       DWORD dwCreationFlags,
  _Out_opt_  LPDWORD lpThreadId
 );

 

 HANDLE WINAPI CreateRemoteThread(
  _In_   HANDLE hProcess,
  _In_   LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_   SIZE_T dwStackSize,
  _In_   LPTHREAD_START_ROUTINE lpStartAddress,
  _In_   LPVOID lpParameter,
  _In_   DWORD dwCreationFlags,
  _Out_  LPDWORD lpThreadId
 );


 HANDLE CreateRemoteThreadEx(
  _In_       HANDLE hProcess,
  _In_opt_   LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_       SIZE_T dwStackSize,
  _In_       LPTHREAD_START_ROUTINE lpStartAddress,
  _In_opt_   LPVOID lpParameter,
  _In_       DWORD dwCreationFlags,
  _In_opt_   LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList,
  _Out_opt_  LPDWORD lpThreadId
 );
 ※ CreateRemoteThreadEx 의 경우 Windows 7 상위계열에서만 사용가능
 

 < 출처 >

 http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453(v=vs.85).aspx

 http://msdn.microsoft.com/en-us/library/windows/desktop/ms682437(v=vs.85).aspx

 http://msdn.microsoft.com/en-us/library/windows/desktop/dd405484(v=vs.85).aspx

 

 

귀찮으니 사용 방법은 출처를 확인.

 

위 빨간색 부분을 제일 많이 애용한다.

 

그럼, 위 쓰레드는 어떤식으로 함수가 호출되는가 ?

 

[WIndows XP]

_beginthread -> CreateThread -> CreateRemoteThread

[Windows 7]

_beginthread -> CreateThread -> CreateRemoteThread -> CreateRemoteThreadEx

※ Windows 7 은 분석해보지 않아서 확실하지 않습니다.

 

이런식으로 호출된다.

 

결론적으로 윈도우에서는 CreateRemoteThread로 호출하는게 제일 빠른 결론이 나옴.

 

이야기가 산으로 갔는데, 쓰레드생성시 Parameter에 지역변수를 사용하면 안된다 ?

 

답은 'NO' 이다. 사용해도 되는데, 문제는 정적변수로 지역변수를 사용해야한다.

 

 

 잘못된 예

 

 #include <windows.h>

 #include <stdio.h>

 

 DWORD WINAPI CallThread(LPVOID pVal){

   DWORD dwCnt = 0;

 

    if ( pVal )

       while(dwCnt++<10){

          printf("%d\n",*(int *)pVal);

          Sleep(1000);

       }

    return 0;

 }

 

 HANDLE WINAPI Call(){

    DWORD dwThreadId;

    HANDLE hThread;

    int nVal = 1;

 

    hThread = CreateThread(NULL,0,CallThread,&nVal,0,&dwThreadId);

    if ( hThread )

       return hThread;

    return NULL;

 }

 

 int main(void){

    HANDLE hThread;

 

    hThread = Call();

    if ( hThread ){

       WaitForSingleObject(hThread,INFINITE);

       CloseHandle(hThread);

    }

 

    return 0;

 }

 

 

 

 올바른

 

 #include <windows.h>

 #include <stdio.h>

 

 DWORD WINAPI CallThread(LPVOID pVal){

   DWORD dwCnt = 0;

 

    if ( pVal )

       while(dwCnt++<10){

          printf("%d\n",*(int *)pVal);

          Sleep(1000);

       }

    return 0;

 }

 

 HANDLE WINAPI Call(){

    DWORD dwThreadId;

    HANDLE hThread;

    static int nVal = 1;

 

    hThread = CreateThread(NULL,0,CallThread,&nVal,0,&dwThreadId);

    if ( hThread )

       return hThread;

    return NULL;

 }

 

 int main(void){

    HANDLE hThread;

 

    hThread = Call();

    if ( hThread ){

       WaitForSingleObject(hThread,INFINITE);

       CloseHandle(hThread);

    }

    return 0;

 }

 

 

이런 느낌이다.

 

그럼 왜 지역 변수로 사용하면 안되는걸까 ?

 

정적 변수의 경우엔 '자신만의 저장소(메모리주소)를 독립적으로 가지고 있는' 반면

 

지역 변수의 경우엔 '함수 호출시에 변수를 할당' 하기 때문이다.

 

따라서, 해당 함수가 끝나면, 할당된 지역변수는 해제되고 해제된 지역변수 메모리 주소는

 

다른 함수등에 의해 새로운 값으로 덮어씌워지게 된다.

 

물론, 지역변수가 해제되고 해당 지역변수의 주소에 있는 메모리의 값이 변동이 없다면

 

값은 바뀌지 않는다.

(하지만, 그런일은 거의 없다.)

 

[ 잘못된 예의 예제 그림 ]

 

 

[ 올바른 예의 예제 그림 ]

 

그림으로 나타내면 이런 느낌 ?

 

Local Memory 부분에서 서로의 값이 충돌하는 사태가 벌어져서 지역변수로 쓰면 안된다는 이야기.

 

그럼 여기서 문제

 

 

 

이런것도 가능할까 ?

 

 

이야기는 여기서 마치도록 하겠습니다 ' ' ;

 

 

 

 

 

Category
분류 전체보기 (605)
Notice (6)
Programming (79)
DISKER (1)
FSCH (7)
Caption (0)
Rest Time ! (443)
Hobby (64)
Tour (5)
Blind Post (0)
Recent Post
Recent Comment
Link
Calender
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Total :
Today :
Yesterday :