 |
|
 |
I am creating a vs2005 vc++ application and trying to get a secondary thread setup and working. I have read through the various postings and tried to put some code together but it won't compile.
I am trying to start the new thread from a menu item via a message handler based in my application's 'CView' based class. I have created a new class of my own (GcWorkerThread) and is derived from CWinThread, and contains a member function 'GcThreadFunction'
calling code:
int x; CWinThread *pThread = AfxBeginThread (GcThreadFunction, x);
UINT GcWorkerThread::GcThreadFunction (LPVOID pParam) { int t; for (int y=0; y<1000000; y++ { }
}
When is comes to compiling the code I get an error: "Error C3867 'GcWorkerThread::GcThreadFunction' function call missing argument list use &GcWorkerThread::GcThreadFunction to create a pointer to member"
What am I doing wrong? :(
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
try this.
int x; CWinThread *pThread = AfxBeginThread (GcThreadFunction, &x);
Thanks and Regards, Selvam, http://www.wincpp.com
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I am working in Microsoft VC++. Now i am learning threading concepts. I executed following code segment in MFC Project. There is no error in program. It's executing but the output wrongly get stored in test.txt file and test1.txt file. I want to know real difference between THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_HIGHEST. See my code segment i given the THREAD_PRIORITY_HIGHEST for WorkerThreadProc which in turn will write the output in test.txt. I used THREAD_PRIORITY_NORMAL for WorkerThreadProc1 to write the output in the file test1.txt. But it's not correctly working. I expected the output to print 100 values in the file test.txt but it is randomly writing the value in the files test.txt and test1.txt. May u clearly give the definition of thread priority and how to use in my program to achieve the output what i expected....
UINT WorkerThreadProc( LPVOID Param ) //Sample function for using in AfxBeginThread { CFile file; file.Open("C:\\test.txt",CFile::modeCreate|CFile::modeWrite); CString strValue; for(;i<=1000;i++) { strValue.Format("Value:%d\n",i);
file.Write(strValue,strValue.GetLength()); // Write to the file for worker thread using AfxBeginThread } file.Close();
return TRUE; } UINT WorkerThreadProc1( LPVOID Param ) //Sample function for using in AfxBeginThread { CFile file; file.Open("C:\\test1.txt",CFile::modeCreate|CFile::modeWrite); CString strValue; //AfxMessageBox("Hai"); for( i=0;i<=1000;i++) { strValue.Format("Value:%d\n",i); file.Write(strValue,strValue.GetLength()); // Write to the file for worker thread using AfxBeginThread } file.Close();
return TRUE; }
void CThread_AfxBeginDlg::OnOK() { // TODO: Add extra validation here //CDialog::OnOK(); AfxBeginThread(WorkerThreadProc,NULL,THREAD_PRIORITY_HIGHEST,0,0,NULL); AfxBeginThread(WorkerThreadProc1,NULL,THREAD_PRIORITY_NORMAL,0,0,NULL); MessageBox("See the output in C:\\test.txt and test1.txt"); }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
I have a COM Dll tht has the funtionality of building the AudioCapture Directshow graph and capturing audio from audio line available on the Audio Capture Card. Inside the dll there a StartCapture() funtion that creates a Audio capture graph by calling a BuildGraph() funtion and then it starts a thread "CaptureThread". Now inside BuildGraph() function i am using using SampleGrabber Filter(with BufferCB() overwritten) to capture audio from Audio LineIn. I start one more thread "ProcessThread" in the Constructor of SampleGrabber.So when the SampleGrabber object is created in BuildGraph() ProcessThread is started. Now in my application i am calling an interface of my above COM Dll. So now ,if i call StartCapture() from my application multiple times , will it create multiple CaptureThread and ProcessThread ? How ll it behave ? I have not worked much with threading , so need help.
regards ravi
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
Hi all; I am implementing a program wherein i got to return a value from a thread, can anyone help me with this regard..
Thanks in advance
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
You can give the Thread a start parameter object in which you can write a value. Or the return value of the thread, buts it depends how you created it.
Greetings from Germany
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I am working on application in which i have to terminate different threads and restart it. I am using __beginthreadex function to create a thread. I cant make the use of _endthreadex functionality. Is there any other way other than TerminateThread function to terminate different threads from other threads or from other process or If I am using TerminateThread function, is there any way to deallocate the TLS and stack memory of the terminated thread.
Thanks in Advance
Nitin
|
| Sign In·View Thread·PermaLink | 1.00/5 |
|
|
|
 |
|
 |
hi this is very useful article for me.. i need to know how to pass multiple arguments to the member function which is used in the createthread()
this is urgent help me to solve
thanks in advance K.C.S
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
you can create structure and convert into void pointer and pass to Thread function.
Thanks and Regards, Selvam, http://www.wincpp.com
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
hi selvam, thanks for your reply
i used string concadination and passed then i tokenized it in the function how ever it is good approach
thanks selvaraj
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
hi one more problem is i want to create thread for member function by using the object .. how todo that ex. class a { int abx(char[20]) }
..... winmain() { a ab; CreateThread(0,0,ab.abx,NULL,NULL,&pid); }
i can't declare that function abx() as static because, it calls anothe member function of non static
help me to solve this...
iam trying this to solve the problem in message loop iam calling this function in winmain()
when this function is executing any message to window like close/minimize is not processed.. if you give solution with little code it will be the most useful
waiting for your reply selvaraj
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
you can pass entire class object. We can access the class object within Thread function.
Thanks and Regards, Selvam, http://www.wincpp.com
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
Hi friends, I am fetching data from a buffer at an interval of every 100 ms adding the same data to quque. at every 100 ms (depending on the system timer) i am spawning a thread to do this job. The main thread is rendering some model depending on the data available in quque. But The system timer fail to fire on every 100 ms. I am working with VC++ compiler. if any better approch is available then please inform.
|
| Sign In·View Thread·PermaLink | 1.50/5 |
|
|
|
 |
|
 |
Hello!
Good job! But...
obj is completely unprotected from each thread which goes into this global object to ket it's starting y-row for the ellipse but there can be race conditions where two threads get the same row -- for example, set the for(int i = 0; i <= 400; i=i+50) to for(int i = 350; i <= 400; i=i+50)
and watch what happens (on some machines). You would expect two rows of balls to draw (i=350, i=400) but on my machine only one draws because both threads see the row as obj.a = 400 -- i.e., by the time the first thread gets to the obj.a of 350 set in the first loop iteration and launch of 1st thread, the second thread has already set obj.a to 400. Please mention need for synchronization and a hack fix would be to do a Sleep(100) after the:
AfxBeginThread(Threadproc, &obj);
This gives the launched thread a chance to pull out it's info. Also, I am not familiar with HWND and HDC which also live inside the global structure and each thread repeatedly uses this shared global object.
Here is what I did for a cleaner fix:
th obj; // same as before CRITICAL_SECTION g_CritSect; // new bool g_bInitialized = false; // new
UINT Threadproc(LPVOID param) { // EnterCriticalSection(&g_CritSect); #if 0 th *temp= (th*)param; // old way #else th *temp = (th*)param; th thLocal; th *pthLocal = &thLocal; pthLocal->a = temp->a; pthLocal->hWnd = temp->hWnd; pthLocal->hDC = temp->hDC; temp = pthLocal; LeaveCriticalSection(&g_CritSect); #endif HDC dc= GetDC(temp->hWnd); // same as before . .
void CThread3View::OnThreadStartthread() { if(!g_bInitialized) { g_bInitialized = true; InitializeCriticalSection(&g_CritSect); }
for(int i = 350; i <= iNumBalls; i=i+50) { EnterCriticalSection(&g_CritSect); obj.a = i; obj.hWnd = GetSafeHwnd(); AfxBeginThread(Threadproc, &obj); // was &obj.a } // DeleteCriticalSection(&g_CritSect); // exit will have to do this //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% }
See ya!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Sorry, I have to correct myself ... the critical section spanned thread code which is a no-no. A far simpler solution would be to leave code as is and just make the following changes:
void CThread3View::OnThreadStartthread() { // i 350, 400 are y-coord of upper left for each row of ellipse/circles for(int i = 350; i <= 400; i=i+50) { obj.hWnd = GetSafeHwnd(); obj.a = i; obj.hWnd = GetSafeHwnd(); th *pth = new th; *pth = obj; // copy the structure for thread usage AfxBeginThread(Threadproc, pth); // was &obj.a } }
Cleaning up the allocated memory is an exercise for the reader.
See ya!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
obj is completely unprotected from each thread which goes into this global object to ket it's starting y-row for the ellipse but there can be race conditions where two threads get the same row -- for example, set the for(int i = 0; i <= 400; i=i+50) to for(int i = 350; i <= 400; i=i+50)
and watch what happens (on some machines). You would expect two rows of balls to draw (i=350, i=400) but on my machine only one draws because both threads see the row as obj.a = 400 -- i.e., by the time the first thread gets to the obj.a of 350 set in the first loop iteration and launch of 1st thread, the second thread has already set obj.a to 400. Please mention need for synchronization and a hack fix would be to do a Sleep(100) after the:
AfxBeginThread(Threadproc, &obj);
This gives the launched thread a chance to pull out it's info. Also, I am not familiar with HWND and HDC which also live inside the global structure and each thread repeatedly uses this shared global object.
Here is what I did for a cleaner fix:
th obj; // same as before CRITICAL_SECTION g_CritSect; // new bool g_bInitialized = false; // new
UINT Threadproc(LPVOID param) { // EnterCriticalSection(&g_CritSect); #if 0 th *temp= (th*)param; // old way #else th *temp = (th*)param; th thLocal; th *pthLocal = &thLocal; pthLocal->a = temp->a; pthLocal->hWnd = temp->hWnd; pthLocal->hDC = temp->hDC; temp = pthLocal; LeaveCriticalSection(&g_CritSect); #endif HDC dc= GetDC(temp->hWnd); // same as before . .
void CThread3View::OnThreadStartthread() { if(!g_bInitialized) { g_bInitialized = true; InitializeCriticalSection(&g_CritSect); }
for(int i = 350; i <= iNumBalls; i=i+50) { EnterCriticalSection(&g_CritSect); obj.a = i; obj.hWnd = GetSafeHwnd(); AfxBeginThread(Threadproc, &obj); // was &obj.a } // DeleteCriticalSection(&g_CritSect); // exit will have to do this //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% }
See ya!
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
|
 |
|
 |
Your article contains several errors/problems:
- In the paragraph 'MFC Multithreaded', you show how to start a thread. But you forgot to show how to wait for it to exit (which you did for the _beginthread() example). When you start a thread just by calling AfxBeginThread() like your sample shows it, the thread will delete its CWinThread instance automatically when it terminates. Because of this, you cannot safely touch the CWinThread object in the main thread, leaving you with no way to check whether the thread is still running or not. To correct this behaviour, do the following: CWinThread* pThread = AfxBeginThread(ThreadFunction, pData, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); pThread->m_bAutoDelete = FALSE; pThread->ResumeThread(); The CREATE_SUSPENDED flag means that the thread will be created, but it will not immediately start running. Setting the CWinThreads m_bAutoDelete member to false means that when the thread terminates, it will not delete the CWinThread object. As a result of this, you can use the CWinThread in the main thread since you can rely on it to not go away while you're touching it. Since the thread was created in suspended state, you have to resume it, so that it actually runs.
Now, later in your application, you can wait for your thread like this: WaitForSingleObject(pThread->m_hThread, INFINITE); Then you can delete the CWinThread instance (remember: it doesn't delete itself anymore).
The reason that I mention this is this: When you just start a thread, and never care about waiting for its termination, you have no control over the threads state. For example: If your application is shutting down, you should make sure that all your spawned threads have finished their work and terminated properly. The way to do this is to signal them to terminate themselves (in any way you like, e.g. with a event), and then wait for them to terminate (WaitForSingleObject on their thread handle).
- In the paragraph 'Win32 Multithread', you write that a thread can terminate itself with TerminateThread(). This is not what this function is intended for. Its purpose is to terminated another thread. However, terminating another thread with TerminateThread() is generally a very bad idea. As is documented in MSDN Library, the usage of this function can lead to unpredicted behaviour (e.g. deadlocks in your application), and it doesn't free the thread's stack. It shouldn't be used at all. The correct way of terminating another thread is to signal it (e.g. through an event) that it should terminate itself; then wait for it to terminate. This is the way to go if you want your application to behave predictable. Additionally, I would recommed to everyone who wants to learn about multithreading to read more than one article. Most articles that I've read are missing some important points; so by reading several of them, you should get the whole picture. This article, for example, doesn't mention the most important aspect of multithreading: synchronization. Additionally, reading different articles provides you with different techniques and approaches. Especially in a complicated field like multithreading, the more you know, the better it is.
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
 |
Hi,
This article focused on beginners. Now, I am also beginner. You mentioned multithreading has complicated field. I accept.
In MFC multithreaded, if we use for this method,
CWinThread* pThread = AfxBeginThread(ThreadFunction, pData, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); pThread->m_bAutoDelete = FALSE; pThread->ResumeThread();
We delete CwinThread Object in the following method.
DWORD dwExitCode; // get thread exit coe ::GetExitCodeThread (pThread->m_hThread, &dwExitCode); if (dwExitCode == STILL_ACTIVE) { // The thread is still running. } else { // The thread has terminated. Delete the CWinThread object. delete pThread; }
As you mentioned TerminateThread function, I mentioned already (it doesn't free the thread's stack).
Ok. Anyway thank you for your valuable commands and suggestions.
|
| Sign In·View Thread·PermaLink | 1.00/5 |
|
|
|
 |
|
 |
The way you just described to wait for the thread to terminate has a bug: You just try ::GetExitCodeThread() once. But if you get STILL_ACTIVE, you just continue to run, not waiting for the thread. So the correct version would be like this:
DWORD dwExitCode = STILL_RUNNING; while (dwExitCode == STILL_RUNNING) { GetExitCodeThread(pThread->m_hThread, &dwExitCode); }
Now you really wait for the thread's termination. Unfortunately, this method has a problem: it's consuming too much CPU time (probably ~ 100%), which is not what you usually want. One way to fix it would be to call Sleep() once per loop (e.g. for Sleep(100)).
The better way of fixing it is to not use this method. Instead, use the method I already described in my previous comment:
WaitForSingleObject(pThread->m_hThread, INFINITE); If you need the exit code, you can call GetExitCodeThread() now.
WaitForSingleObject(pThread->m_hThread, INFINITE); GetExitCodeThread(pThread->m_hThread, &dwExitCode);
I don't know from where you got the impression that you must use GetExitCodeThread() for threads created by MFC, but it's not true. You can have a look at MFC's source code if you don't believe me.
So, as a reference, here's a code sample showing the whole life cycle of a thread:
CWinThread* pThread = AfxBeginThread(ThreadFunc, param, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); pThread->m_bAutoDelete = FALSE; pThread->ResumeThread();
::WaitForSingleObject(pThread->m_hThread, INFINITE); DWORD dwExitCode = 0; ::GetExitCodeThread(pThread->m_hThread, &dwExitCode);
delete pThread; pThread = NULL;
Maybe you want to update your article, so that other's don't have to read the comments to get all the information.
Continue your work on this area, and soon you will master it
|
| Sign In·View Thread·PermaLink | 4.47/5 |
|
|
|
 |
|
|
 |