none
create child thread for reading std::map RRS feed

  • Question

  • Hi, 

    I am working on an MFC dialog based application in VS2015.

    In my application with my main thread, I am continuously inserting data to my map data structure. Like,

    [1, A]

    [2, B], and so on.

    Now I want to create a child thread which will continuously read this map and display/update the values in ListCtrl of my Dialog.

    Earlier I was not using any data structure and directly updating the data to the UI. But now I have to add the filter to the list control, therefore as per the user's condition in the filter, I need to populate the list on the UI.

    So as soon as the user apply the filter I need that the child thread read the elements of map from the beginning then apply the filter and update the UI.

    Kindly guide me in solving my problem.  How to synchronize the main thread and child thread. Please help me with the best approach.

    Thanks in Advance.     


    Thanks & Regards, Mayank Agarwal

    Thursday, May 25, 2017 1:11 PM

All replies

  • In my application with my main thread, I am continuously inserting data to my map data structure. Like,
    ...
    Now I want to create a child thread which will continuously read this map and display/update the values in ListCtrl of my Dialog.

    I suggest you do it the other way round - keep all UI operations in the main (UI) thread and the UI responsive to user actions.

     How to synchronize the main thread and child thread. Please help me with the best approach.

    Whatever is shared between the threads (presumably the map data) should be accessed within the context of a locked critical section
    (CCriticalSection in MFC).

    Dave

    Thursday, May 25, 2017 1:55 PM
  • Why do you need a child thread? Is your map very large?

    If you do use a second thread, it is always best to manipulate the GUI in the main thread. Do not have the child thread directly manipulate controls like your ListCtrl.

    There are two simple ways to transfer the data from the child thread back to the main thread:

    1. Use SendMessage(). This transfers execution the the GUI thread (which owns the window), but will not return until the task is accomplished. Therefore you can pass a pointer to the data to be transferred. You need to be careful not to block your program when using SendMessage(), but IMHO this fear is exaggerated. As long as the main thread is just "keeping the GUI alive" there should be no problem.

    2. Use PostMessage(). This returns immediately, so you need to put the data on the heap, and have the handler in the GUI thread delete it when it is finished.

    How is the map itself maintained? You must take care not to have the main thread modify the map while the second thread is processing the filter.


    David Wilkinson | Visual C++ MVP

    Thursday, May 25, 2017 2:16 PM
  • I suggest you do it the other way round - keep all UI operations in the main (UI) thread and the UI responsive to user actions.

    Actually I will explain you the behavior is bit more detail. the data which I am inserting in the map is coming continuously from one of my MFC extension static library. that library function is running in a child thread from my application(main thread). the sending of data from the library to my dialog class is by using SendMessage().

    In my Dialog class I am handing the message and inserting in the map.

    So now how can I change this behavior?  

    Should I create another child thread to handle the message coming from dll? and for updating the UI I should use WM_TIMER. 

    Kindly suggest. the map will be having huge data(10million+ elements) or may be more.


    Thanks & Regards, Mayank Agarwal

    Friday, May 26, 2017 6:27 AM
  • I suggest you do it the other way round - keep all UI operations in the main (UI) thread and the UI responsive to user actions.

    Actually I will explain you the behavior is bit more detail. the data which I am inserting in the map is coming continuously from one of my MFC extension static library. that library function is running in a child thread from my application(main thread). the sending of data from the library to my dialog class is by using SendMessage().

    In my Dialog class I am handing the message and inserting in the map.

    Yes, this is the SendMessage() method that I suggested to you. The SendMessage() call does not return until the message is handled, but the handler runs in the context of the target window, which is what you want.


    David Wilkinson | Visual C++ MVP

    Friday, May 26, 2017 10:11 AM
  • the data which I am inserting in the map is coming continuously from one of my MFC extension static library. that library function is running in a child thread from my application(main thread). the sending of data from the library to my dialog class is by using SendMessage().
    In my Dialog class I am handing the message and inserting in the map.

    That sounds fine, you're keeping the UI operation in the UI thread.

    Kindly suggest. the map will be having huge data(10million+ elements) or may be more.

    And how big are the elements - i.e. are you potentially going to run out of memory on 32-bit systems?

    Dave

    Friday, May 26, 2017 10:40 AM
  • And how big are the elements - i.e. are you potentially going to run out of memory on 32-bit systems?

    Memory is not the constraint, its manageable.

    problem starts as soon as I apply the filter. My application main thread job is to add the data into the map coming from the library as well as insert the same data(unfiltered) on the listctrl of the dialog.

    Now as soon as I apply the filter on the listctrl. I want to do the following tasks.

    1. The main thread should continue pushing the data in the map.

    2. The main thread should stop pushing the data to the UI (as this is unfiltered data)

    3. the UI should be cleaned up and should be populated with the filtered data ONLY.

    So to perform these above tasks I was thinking of the child thread which will be applying filter on the map data and push filtered data to the Listctrl of the dialog, as my main thread is busy in pushing the data in the map from the SendMessage of the library.

    Here I am stuck. 


    Thanks & Regards, Mayank Agarwal

    Friday, May 26, 2017 11:35 AM
  • And how big are the elements - i.e. are you potentially going to run out of memory on 32-bit systems?

    Memory is not the constraint, its manageable.

    problem starts as soon as I apply the filter. My application main thread job is to add the data into the map coming from the library as well as insert the same data(unfiltered) on the listctrl of the dialog.

    Now as soon as I apply the filter on the listctrl. I want to do the following tasks.

    1. The main thread should continue pushing the data in the map.

    2. The main thread should stop pushing the data to the UI (as this is unfiltered data)

    3. the UI should be cleaned up and should be populated with the filtered data ONLY.

    So to perform these above tasks I was thinking of the child thread which will be applying filter on the map data and push filtered data to the Listctrl of the dialog, as my main thread is busy in pushing the data in the map from the SendMessage of the library.

    Here I am stuck.


    Thanks & Regards, Mayank Agarwal

    So there actually three threads: the main GUI thread, the Data Thread that sends entries to be pout in the map, and the Filter Thread that applies the filter to generate the items to be put in the ListCtrl. Is this correct?

    Let's assume the above, and suppose that the Filter Thread also uses SendMessage() back to the Main Thread. This should be no problem -- the Data Thread and Filter Thread messages will be processed in the order they are received.

    The problem is synchronization of the map-- presumably the Main Thread should not alter the map while the Filter Thread is applying the filter to it.

    One idea; have the Main Thread add items not to the main map, but to a smaller temporary map. Whenever the Filter Thread is inactive, add the items in the temporary map to the main map, clear the temporary map, and start the filter thread running again with the updated map.

    So how do you know when the Filter thread is finished? The method I would use is to have the filter thread use PostMessage() to the Main Thread when it has finished processing the map and is about to exit. In the handler, you can use WaitForSingleObject() on the thread handle to check that the thread has really exited. This should not block, because the Filter Thread has either already exited, or is about to.

    Or in C++11, there is threading support that is easier to use than these Windows-specific methods, but I have not used this myself.


    David Wilkinson | Visual C++ MVP


    • Edited by davewilk Friday, May 26, 2017 1:47 PM
    Friday, May 26, 2017 1:40 PM
  • problem starts as soon as I apply the filter. My application main thread job is to add the data into the map coming from the library as well as insert the same data(unfiltered) on the listctrl of the dialog.

    Perhaps your worker thread should put the data into the map and just notify the main UI thread of the updated data?

    Now as soon as I apply the filter on the listctrl. I want to do the following tasks.
    1. The main thread should continue pushing the data in the map.
    2. The main thread should stop pushing the data to the UI (as this is unfiltered data)
    3. the UI should be cleaned up and should be populated with the filtered data ONLY.

    So to perform these above tasks I was thinking of the child thread which will be applying filter on the map data and push filtered data to the Listctrl of the dialog

    Before you try to solve a problem that may not exist, find how long it'll take to update the map, and how long it'll take to filter
    the data. If you've got multiple threads concurrently manipulating the map you'll have to ensure any operations are locked to
    prevent corruption and multiple threads will only help you if they have something useful to do and your UI is otherwise
    unresponsive..

    I recommend that your main UI should be the only thread that alters the UI controls.

    Dave

    Friday, May 26, 2017 1:44 PM