Old February 25th, 2004, 11:40 AM
Member
 
Join Date: Oct 2003
Posts: 204
urika is an unknown quantity at this point (<10)
putting values in void *arglist

hi ,
i want to run a threads using _beginthread(...)
(no MFC)
inside the threadfunc i want to call a function with many variables.
how do i use the void *arglist so it points to a few variables ?
i hope my question makes sence 
thank u
Reply With Quote
  #2    
Old February 25th, 2004, 11:47 AM
gstercken's Avatar
Moderator
Power Poster
 
Join Date: Sep 2002
Location: 14° 39'19.65"N / 121° 1'44.34"E
Posts: 9,815
gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)
Re: putting values in void *arglist

Quote:
Originally posted by urika 
how do i use the void *arglist so it points to a few variables ?
Usually by creating a class or struct which contains the variables.
You would then use the void* to pass the pointer to an instance of
that class or struct, which you would have to cast back to the actual
type before accessing the members.
__________________
Guido Stercken-Sorrenti
Reply With Quote
  #3    
Old February 25th, 2004, 11:51 AM
Member
 
Join Date: Oct 2003
Posts: 204
urika is an unknown quantity at this point (<10)
thanks!
Reply With Quote
  #4    
Old February 29th, 2004, 05:34 AM
Member
 
Join Date: Oct 2003
Posts: 204
urika is an unknown quantity at this point (<10)
i call a function :
Code:
 bool MapViewInit(GEO p1, GEO p2, DISPLAY Disp, CONTROL Ctrl, HINSTANCE hInst)
{
		MapThreadArgList maparglist;  ////?????
		maparglist.Ctrl=Ctrl;
		maparglist.Disp=Disp;
		maparglist.p1=p1;
		maparglist.p2=p2;
		maparglist.hInst=hInst;
		HANDLE handle1 =(HANDLE)_beginthread( MapThreadFunc,0,
(void *)&maparglist); // create thread COUT << "\n >>> MapViewInit Run Successfully <<<\n"; return true; }
in order to run the thread i do :
Code:
void MapThreadFunc( void* args )
{
		GEO p1;
		GEO p2;
		DISPLAY Disp;
		CONTROL Ctrl;
		HINSTANCE hInst;
		MapThreadArgList arglist = *((MapThreadArgList*)args);
		p1=arglist.p1;
		p2=arglist.p2;
		Disp=arglist.Disp;
		Ctrl=arglist.Ctrl;
		hInst=arglist.hInst;
...
...
...
after i cast back to MapThreadArgList the info in arglist.p1 (and the others ) is lost.
what am i doing wrong?
Reply With Quote
  #5    
Old February 29th, 2004, 06:02 AM
gstercken's Avatar
Moderator
Power Poster
 
Join Date: Sep 2002
Location: 14° 39'19.65"N / 121° 1'44.34"E
Posts: 9,815
gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)gstercken has a reputation beyond repute (3000+)
Quote:
Originally posted by urika 
what am i doing wrong?
You are creating maparglist on the stack - it will be destroyed when it gets out of
scope (when you return from MapViewInit()). Allocate it on the heap, or keep it as a
member variable instead.
__________________
Guido Stercken-Sorrenti
Reply With Quote
  #6    
Old February 29th, 2004, 07:55 AM
Member
 
Join Date: Oct 2003
Posts: 204
urika is an unknown quantity at this point (<10)
thanks , it now works
Reply With Quote

결론
구조체를 사용하여 쓰레드에 넘겨줄 인수를 모두 넣는다. (구조체 정의를 전역변수로 해야 함)
구조체의 객체를 만든 다음 객체멤버에 값을 넣어준다.
통째로 객체를 넘겨준다.
스레드에서 구조체의 객체를 만들어 파라메터의 객체를 받는다.
쓰면된다~ 

'Development > C/C++' 카테고리의 다른 글

[Mutex Thread 동기화 예제]  (0) 2011.11.30
[Sleep함수]  (0) 2011.11.29
[CreateThread(), _beginthread(), _beginthreadex()의 차이]  (0) 2011.11.22
[select FD_SET FD_Zero FD_Clr FD_IsSet]  (0) 2011.11.22
[_beginthreadex 형변환문제]  (0) 2011.11.22
Posted by cyj4369
,
윈도우즈에서 스레드를 생성하는 API는 CreateThread(), _beginthread(), _beginthreadex() 이렇게 3개의 함수가 존재합니다. 

CreateThread()와 _beginthread(), _beginthreadex()의 차이점은 다음과 같습니다.
  • CreateThread()는 스레드를 생성하는 기능만 담당한다.
  • _beginthread(), _beginthreadex()는 내부적으로 CreateThread() 를 사용하여 스레드를 생성하고 C Runtime library에서 내부적으로 필요로 하는 메모리 영역을 초기화 해주는 역할을 하게 됩니다. 초기화 되는 메모리 영역은 각 스레드 마다 따로 관리되게 됩니다.


그렇다면 _beginthread(), _beginthreadex()의 차이는 무엇일까요? 의외로 이 차이에 대해서 대답을 명쾌하게 해주는 분이 많지가 않습니다. 이제부터 그 차이를 설명해 보도록 하겠습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  
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 
);

함수 원형을 보고 알 수 있는 파라메터에 의한 차이점은 다음과 같습니다.

  • _beginthreadex()는 security를 이용하여 보안 관련 설정을 할 수 있다.
  • _beginthreadex()는 initflag를 이용하여 스레드의 초기 동작을 정의 할 수 있다.
  • _beginthreadex()는 thrdaddr을 이용하여 thread id를 받을 수 있다.
  • _beginthreadex()는 __stdcall 형식의 함수 포인터를 thread 실행 함수로 받는다.
  • _beginthreadex()는 함수 실행 실패시에 0을 리턴한다. (_beginthread는 -1을 리턴한다.)

여기에 더해서 가장 중요하게 기억해야 할 한가지의 차이점이 더 존재합니다. (이 내용이 글을 쓰는 이유이기도 합니다. ^^)
_beginthread()는 스레드가 생성되고 스레드 함수의 실행이 종료 되면 스레드의 정리 작업을 해주게 됩니다. 이러한 형태는 편리한 점이 있지만 단점도 존재하게 되는데 바로 스레드의 실행 완료후에 해당 스레드의 정보를 조회 할 수 있는 방법이 없다는 것입니다. 

예를 들어 스레드의 종료시에 exit 코드가 무엇인지 알기 위해서 GetExitCodeThread()를 사용할 수 있습니다. 이때 첫번째 인자로 스레드의 핸들을 파라메터로 넘겨줘야 되는데 _beginthread()로 생성된 스레드의 핸들은 GetExitCodeThread()를 사용할 수 없습니다. 

1
2
3
4
BOOL WINAPI GetExitCodeThread(
  HANDLE hThread,
  LPDWORD lpExitCode
);

왜 그럴까요? _beginthread()로 생성된 스레드 핸들은 스레드 함수의 실행이 종료될 때 _beginthread() 내부에서 CloseHandle()을 호출하기 때문에 프로그래머가 GetExitCodeThread()를 사용할 수 있는 시점에서는 이미 소멸된 핸들이 되기 때문입니다.

_beginthreadex()는 위와 같은 문제를 해결하기 위해 스레드가 종료될때 내부적으로 CloseHandle()를 호출하지 않고 사용자가 명시적으로 해제하도록 변경되었습니다.

결과적으로 내용을 정리하면 다음과 같습니다.

  • _beginthread()로 생성된 스레드 핸들은 스레드 종료시에 CloseHandle()이 내부적으로 호출되어 신경쓸 필요가 없지만 스레드 함수 완료 후 스레드 핸들을 이용한 어떠한 API 함수도 실행 시킬 수 없습니다.
  • _beginthreadex()로 생성된 스레드 핸들은 스레드가 실행완료된 후 내부적으로 CloseHandle()을 실행시키지 않기 때문에 스레드 핸들을 이용한 API 함수를 실행할 수 있지만 사용자가 명시적으로 CloseHandle()을 호출해 주어야 합니다. 만약 CloseHandle()을 해주지 않으면 핸들이 계속 쌓이게 되는 Resource leak이 생기게 됩니다.
Posted by cyj4369
,
 
2003-01-09 오후 8:18:50   /  번호: 270644   category: VC++ 일반  /  조회: 167
 [급질문]_beginthreadex 에서 BOOL 함수 호출..그리고 파라메터  
리턴 값이 BOOL 인 함수를 쓰레드로 쓸려면 3번째 파라미터에 어떻게 선언해줘야되죠??
그리고 구조체를 파라미터로 넘길려고 그러는데..자꾸 이런에러가 뜨네요.
error C2664: '_beginthreadex' : cannot convert parameter 3 from 'unsigned int (struct st_ComPort *)' to 'unsigned int (__stdcall *)(void *)'
        None of the functions with this name in scope match the target type

어떻게 해야 되죠?? 파라미터를 넘겨야 되죠??
 
  2004-10-15 오전 1:15:26   /  번호: 474101  /  
 Re: _beginthreadex 형변환문제 답변.   
  

 c++ 은 자료형을 엄격히 구분해서 발생하는 문제입니다.


(HANDLE)_beginthreadex(NULL, 0, ClientConn, (void*)clntSock, 0, (unsigned *)&dwThreadID);


요렇게 사용하면 당근 님이 묻는 Error가 발생합니다.


이것땜시 저도 아주 두시간을 헤맸어용...ㅜㅜ;


문제는 세번째 인자에 있습니다. 요걸 이렇게 바꾸면 형변환 문제 해결... 아래 에러 왕짜증..

error C2664: '_beginthreadex' : cannot convert parameter 3 from 'unsigned long (void *)' to 'unsigned int (__stdcall *)(void *)'

        None of the functions with this name in scope match the target type


음 그니까 (HANDLE)_beginthreadex(NULL, 0, (unsigned int(__stdcall*)(void*))ClientConn, (void*)clntSock, 0, (unsigned *)&dwThreadID);


위에걸 이렇게 바꿔주시면 해결 될거에요....^^


즐공하세용!!


출처 : 데브피아(http://www.devpia.com)

Posted by cyj4369
,