Multi Threads... just a simple example plz...

Started by
14 comments, last by crakinshot 21 years, 7 months ago
I''ve looked around and found quite a lot on threads but they are so intertwined with other garbage I cant make heads or tails of it... I tried looking on MSDN but had to give up before I died of dehydration. (Should pin a note on my monitor stating I need supplies before venturing into the labyrinth that is MSDN) So if some one could kindly explain how a thread is formed I would be grateful. Thank you. btw its for a MFC dialog app... if that changes anything... but I purely want to know how to assign a class object to its own thread. thanks. crakinshot
-=CrAKiN:ShOt=-I could put something witty here but I'm not that stupid...
Advertisement
Just use _beginthreadex() to create the thread, and _endthreadex() to stop it.

MSDN says not to use CreateThread() when you are using the C run times because it creates memory leaks...... And even if you are not, just to be safe, stick to _beginthreadex(), its used the exact same way as CreateThread().

Its not so complicated, you just need to fill in a couple options, pass a function pointer, the thread starts.. And to end it you call _endthreadex() from within the thread... They have some code samples on MSDN.

Looking for a serious game project?
www.xgameproject.com
If you''re using MFC, you''ll either want to use ClassWizard to create your own CWinThread-derived class, or use AfxBeginThread. If you''re not using MFC, do as Max_Payne said.

CWinThread-derived class Create a CWinThread-derived class in ClassWizard. Your thread goes in the Run function of your new class. To run the thread:

CMyWinThread* p = new CMyWinThread;p->m_bAutoDelete = true; // not sure if this is set automatically to truep->CreateThread(); 


AfxBeginThread
UINT MyThread(LPVOID param){  // do stuff  return 0;}LPVOID param = 0;AfxBeginThread(MyThread, param); 


cool thx mutex


[edited by - crakinshot on September 10, 2002 3:18:39 PM]
-=CrAKiN:ShOt=-I could put something witty here but I'm not that stupid...
quote:Original post by Max_Payne
And to end it you call _endthreadex() from within the thread...
You can just return from the thread function to end the thread.

Ending a thread from another thread is potentially unsafe, as you might kill it while it''s doing stuff, and thus prevent it from releasing stuff it''s using.

To help you along with _beginthreadex, here''s a header that wraps the call up as if it was CreateThread - and like mutex said, you don''t need to call endthreadex, just let the thread run out. endthreadex is there for "emergency" use.


  /* createthreadex.h */#ifndef CREATETHREADEX_H_#define CREATETHREADEX_H_#pragma once#include <process.h>/* ---------------------------------------------------------------------------Q132078: "How to Use _beginthreadex() and _endthreadex()"http://support.microsoft.com/default.aspx?scid=KB;EN-US;q132078&    When developing a multithreaded Win32-based application with Visual C++,    you need to use the CRT thread functions to create any threads that call    CRT functions. To create and terminate threads, use either _beginthread()    and _endthread() or _beginthreadex() and _endthreadex().    If you use the Win32 APIs CreateThread() and ExitThread() instead,    some of the CRT functions used in the thread will not work.    You need to use the CRT functions to both create and end the threads    or you lose the memory that the CRT allocates for the thread.    In addition to preventing memory leaks, using _beginthreadex places    a structured exception handling frame around the thread function    so that the signal function and floating point exceptions work correctly.See also:Win32 Q&A, MSJ July 1999http://www.microsoft.com/msj/0799/win32/win320799.htmWin32 Q&A, MSJ October 1999http://www.microsoft.com/msj/1099/win32/win321099.htmHere are two macro overlays to facilatate this usage:Note:The thread that uses CreateThreadEx to launch new threads shouldalso dispose of any generated thread handle using CloseHandle.    HANDLE MyThread = CreateThreadEx(...);    ...    CloseHandle(MyThread);--------------------------------------------------------------------------- */typedef unsigned (__stdcall *StartAddressT)(void*);#define CreateThreadEx(                         \    lpThreadAttributes,                         \    dwStackSize,                                \    lpStartAddress,                             \    lpParameter,                                \    dwCreationFlags,                            \    lpThreadId                                  \)                                               \ ( (HANDLE) _beginthreadex(                     \	    (void *)        (lpThreadAttributes),   \    	(unsigned int)  (dwStackSize),          \	    (StartAddressT) (lpStartAddress),       \    	(void *)        (lpParameter),          \	    (unsigned int)  (dwCreationFlags),      \    	(unsigned int *) (lpThreadId) ) )#define ExitThreadEx(dwExitCode) _endthreadex((unsigned int)dwExitCode)#endif /* CREATETHREADEX_H_ */  


"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
thanks guys for the help...

its ovois I''ll have to alter the structer of my code to incorperate this... which is annoying cus its working like a charm (except for the freezing... hehe)

anyway thanks;

ps. is there any danger of using the same objects in memory in two different threads? I know deleting objects would be futile with two threads running... but is there a problem with just accessing data?

and also... if say... you have your thread running.

and you want to return a class object back to the calling item. would this have to be done before I close the thread (or just returning 0); or after? my main concern is if I create an object while in a thread then close the thread the data is deleted along with the thread??...
-=CrAKiN:ShOt=-I could put something witty here but I'm not that stupid...
quote:ps. is there any danger of using the same objects in memory in two different threads? I know deleting objects would be futile with two threads running... but is there a problem with just accessing data?


If no threads can change the data in any way, you do not need to synchronize access to the data.

If even one thread can modify the data in any way, you do need to synchronize accesso to the data.

To synchronize a thread, you create a CRITICAL_SECTION object that can be shared between all threads. When a thread is about to access the data, it must call EnterCriticalSection first, and then it must call LeaveCriticalSection after it has finished with the data. The CRITICAL_SECTION object ensures that only one thread gets access to the data at a time, and that each thread''s accesses are performed atomically (that is, all-at-once without interruption by other threads).

I think that MFC has a class that wraps up this CRITICAL_SECTION stuff for you.
quote:and you want to return a class object back to the calling item. would this have to be done before I close the thread (or just returning 0); or after? my main concern is if I create an object while in a thread then close the thread the data is deleted along with the thread??...


No, all threads share the process''s memory space, so they also share the process''s free store. You can freely create an object in one thread and delete it in another.
quote:Original post by null_pointer
I think that MFC has a class that wraps up this CRITICAL_SECTION stuff for you.
Indeed it does:
CCriticalSection g_cs;CString g_sData;  // data that requires synchronizationUINT ThreadOne(LPVOID param){  g_cs.Lock();  sData = "Blah";  g_cs.Unlock();  return 0;}UINT ThreadTwo(LPVOID param){  g_cs.Lock();  sData = "Asdf";  g_cs.Unlock();  return 0;} 


Thread synchronization is absolutely crucial. Any data modification or access needs to be synchronized. If not, your program will leak memory, crash, and do bad things to furry hamsters.

If it''s hard to imagine why such things would happen, just remember that two threads have the potential to execute simultaneously; the functions may run at the exact same time. What this means is that each line of code may be running simultaneously, not just entire blocks. Now try imagining your algorithm running twice at the same time to see if there are any problems.

P.S. It isn''t really truly simultaneous execution unless you have an SMP system, but I''ll leave that for someone else to explain

This topic is closed to new replies.

Advertisement