CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Aug 2004
    Posts
    91

    Post data to a thread

    Hello,

    I am working with a MDI application. I have one thread (THREAD 1) in a user defined class which does background work, i.e reads each line from file does some manipulations and another thread (THREAD 2) in my View class which has to take this data from THREAD 1 and display it in the list ctrl on the view. When I select a file, THREAD 1 and THREAD 2 are started. Now I need to find a mechanism for posting data from Thread 1 to Thread 2. I am trying to use PostThreadMessage, but I am unable to go ahead.

    THREAD 1:
    {
    Read Each Line
    Filter Each Line
    }


    THREAD 2:
    {
    Display Each Line
    }

    THREAD 1 and THREAD 2 should do the work simultaneously so that no time is wasted.

    Can anyone please let me know how PostThreadMessage can be used here.
    Thanks in anticipation of information.

    Madhavi.

  2. #2
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128

    Re: Post data to a thread

    The code in which your thread that is receiving the message, has to run a message loop. See the following link.

    http://msdn.microsoft.com/library/de...sageQueues.asp

  3. #3
    Join Date
    Aug 2004
    Posts
    91

    Re: Post data to a thread

    Hello,
    Below is the code of my two threads, the problem is that all the cstrings posted are not recieved by thread 1, i.e some data is lost in between.
    Can you please let me know where I went wrong?

    THREAD 2
    void StartFiltering(LPVOID lp)
    {
    CLogViewerAppApp* pApp = (CLogViewerAppApp*)AfxGetApp();
    CCriticalSection lock;
    LOG_VIEW_DATA data;

    CFileReader* fp = (CFileReader*)lp;

    lock.Lock();
    CString szLine;
    char ch;//836728
    long c=0;
    for(long k=0;k<1673450;k++)
    {
    ch = fp->Line[k];
    if(ch !='\n')
    szLine += ch;

    if(ch =='\n')
    {

    c++;
    char* pTransfer = new char[szLine.GetLength()]; // allocate memory in thread 1
    strcpy (pTransfer, szLine);
    ::PostThreadMessage(pApp->pThread1->m_nThreadID,WM_FrameToApp,0,(LPARAM) pTransfer) ;
    szLine.Empty();

    }
    }
    lock.Unlock();
    }
    THREAD 1:
    UINT DisplayLog(LPVOID lp)
    {
    CLogViewerAppView *pView = (CLogViewerAppView*)lp;
    CLogViewerAppDoc* pDoc = (CLogViewerAppDoc*)pView->GetDocument();
    pDoc->m_FilterMechanism.StartFilteringLogData();


    MSG msg ;
    while (GetMessage (&msg, NULL, 0, 0))
    {

    if (LOWORD(msg.message) == WM_FrameToApp)
    {
    CString csTmp;
    csTmp = (char*) msg.lParam; // make a copy of string passed in lParam
    delete [] (char*) msg.lParam; // free memory in thread 2


    LOG_VIEW_DATA data = pView->TokenizeData(csTmp);
    pView->m_LogDataCtrl.InsertItem( pView->m_LogDataCtrl.GetItemCount(),data.timeStamp);
    CString str;
    str.Format("%d",data.SequenceNo);
    pView->m_LogDataCtrl.SetItemText( pView->m_LogDataCtrl.GetItemCount()-1,1,str);

    str.Format("%d",data.EventId);
    pView->m_LogDataCtrl.SetItemText( pView->m_LogDataCtrl.GetItemCount()-1,2,str);

    str.Format("%d",data.ThreatID);
    pView->m_LogDataCtrl.SetItemText( pView->m_LogDataCtrl.GetItemCount()-1,3,str);

    pView->m_LogDataCtrl.SetItemText( pView->m_LogDataCtrl.GetItemCount()-1,4,data.ModuleName);

    str.Format("%d",data.ModuleId);
    pView->m_LogDataCtrl.SetItemText( pView->m_LogDataCtrl.GetItemCount()-1,5,str);

    pView->m_LogDataCtrl.SetItemText( pView->m_LogDataCtrl.GetItemCount()-1,6,data.ErrorInfo);
    }
    }
    CLogViewerAppApp* pApp = (CLogViewerAppApp*)AfxGetApp();
    AfxEndThread(pApp->pThread1->m_nThreadID);
    return 0;
    }

    Thanks
    Madhavi

  4. #4
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128

    Re: Post data to a thread

    I tried the following code and it works fine without any missing message.

    Code:
    // TestThread.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    
    /////////////////////////////////////////////////////////////////////////////
    // The one and only application object
    
    CWinApp theApp;
    
    using namespace std;
    
    
    
    UINT display(LPVOID lp)
    {
    	MSG msg;
    	while(GetMessage(&msg, NULL, 0, 0))
    	{
    		if( (int)msg.message != 0)
    			break;
    
    		char *str = (char*)msg.lParam;
    		cout << str << endl;
    
    		delete []str;
    	}
    
    	return 0;
    }
    
    
    int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
    {
    	int nRetCode = 0;
    
    	// initialize MFC and print and error on failure
    	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    	{
    		// TODO: change error code to suit your needs
    		cerr << _T("Fatal Error: MFC initialization failed") << endl;
    		return 1;
    	}
    
    	CWinThread *thread = AfxBeginThread(display, 0);
    
    	Sleep(100); // Wait for the second thread to run.
    	for(int i = 0; i < 10000; ++i)
    	{
    		char *str = new char[100];
    		sprintf(str, "message %d", i);
    
    		PostThreadMessage(thread->m_nThreadID, 0, 0, (LPARAM)str);
    		Sleep(1);  // Give a chance for the other thread(s) to switch over.
    	}
    
    	// End the thread.
    	PostThreadMessage(thread->m_nThreadID, 1, 0, 0);
    
    	Sleep(1000);
    
    	return nRetCode;
    }
    Last edited by Kheun; September 9th, 2004 at 02:44 AM.

  5. #5
    Join Date
    Aug 2004
    Posts
    91

    Re: Post data to a thread

    But for me Thread 2 is able to post all the data lines, but thread 1 is unable to display all the lines. Can you please guess the reason for my problem?

    Thanks
    Madhavi

  6. #6
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128

    Re: Post data to a thread

    Just a guess. In your posting thread, it doesn't have make any Sleep() call. So, it doesn't give the other thread a chance to run and the other thread can only run when the OS context-switches to it. As a result, the message queue for the other thread may be overrun and hence causing you to lost messages.

  7. #7
    Join Date
    Aug 2004
    Posts
    91

    Re: Post data to a thread

    Is there any way to avoid this without using sleep? If I use sleep, my entire process slows down and my main aim of using threads is to speedup the display part.

  8. #8
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128

    Re: Post data to a thread

    It is not necessary to Sleep() but we need to context-switch so that the other thread can clear its message queue. I think there are several ways we can use to work around this limitation. We can first reduce the amount of context-switching required. Reducing the number of call to operator new and delete also helps as memory management calls are also time consuming.

    For example, we can send multiple items in a message instead of one. To further reduce the time needed for memory de/allocation, we can create a memory pool so that the memory can be recycled. To ensure that the message queue is not being overflowed, we can CreateSemaphore() and WaitForSingleObject() to limit the first thread from posting message when the semaphore's count reaches zero count. The semaphore is relinquish when the receiving thread ReleaseSemaphore().

    Hope this helps.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured