Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Help on Multi-Threaded applicaiton [modified]

Help on Multi-Threaded applicaiton [modified]

Scheduled Pinned Locked Moved C / C++ / MFC
questionperformancehelpannouncement
41 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Kiran Satish

    Thanks, I feel like a complete dumbo. I always use CEvent::WaitForSingleObject(,) in many threads so that they wont lock the CPU and never thought of using them here. Maybe I need to start thinking slowly ;P

    PKNT

    M Offline
    M Offline
    Mark Salsbery
    wrote on last edited by
    #19

    :)

    Kiran Satish wrote:

    I always use CEvent::WaitForSingleObject(,) in many threads so that they wont lock the CPU

    Yes!. It also throttles your thread loops so they don't sit there spinning while waiting for the flag to be set, eating all your CPU for 1 processor (each). Mark

    Mark Salsbery Microsoft MVP - Visual C++ :java:

    1 Reply Last reply
    0
    • K Kiran Satish

      Thanks, I feel like a complete dumbo. I always use CEvent::WaitForSingleObject(,) in many threads so that they wont lock the CPU and never thought of using them here. Maybe I need to start thinking slowly ;P

      PKNT

      M Offline
      M Offline
      Mark Salsbery
      wrote on last edited by
      #20

      plus...you can add a terminate event if needed so the threads can be shutdown gracefully. Then you'd wait on multiple objects. Mark

      Mark Salsbery Microsoft MVP - Visual C++ :java:

      1 Reply Last reply
      0
      • M Mark Salsbery

        Flags? no no no :) There's handy synchronization objects for that, something like:

        autoreset events:
        newframeevent
        signalevent

        Loop thread
        do
        {
        waitForSingleObject(newframeevent)
        do analysis on the frame
        SetEvent(signalevent) //signal the camera to get new frame
        update displays and do logs for the current frame
        }
        while(looprunning);

        camera thread
        do
        {
        waitForSingleObject(signalevent)
        get new frame - takes 20ms
        SetEvent(newframeevent)
        }
        while(camrunning);

        The worst thing I see in the flags implementation is two threads modifying the signal flag. Mark

        Mark Salsbery Microsoft MVP - Visual C++ :java:

        K Offline
        K Offline
        Kiran Satish
        wrote on last edited by
        #21

        I tried to implement this in simple way to test and rather than waiting for the event to occur, it runs continuously even I define the timeout value to be INIFINITE

        getsnap()
        {
        start camera thread if not running
        PulseEvent(getnewframe)
        waitForSingleObject(newframeevent, INFINITE)
        return;
        }

        camera thread
        do
        {
        waitForSingleObject(getnewframe, INFINITE)
        get new frame - takes 20ms
        PulseEvent(newframeevent)
        }while(camrunning);

        Here the camera thread continues running even after taking a frame. I am sure 'm missing something here. Sorry for bothering :) . -thanks

        PKNT

        M 1 Reply Last reply
        0
        • K Kiran Satish

          I tried to implement this in simple way to test and rather than waiting for the event to occur, it runs continuously even I define the timeout value to be INIFINITE

          getsnap()
          {
          start camera thread if not running
          PulseEvent(getnewframe)
          waitForSingleObject(newframeevent, INFINITE)
          return;
          }

          camera thread
          do
          {
          waitForSingleObject(getnewframe, INFINITE)
          get new frame - takes 20ms
          PulseEvent(newframeevent)
          }while(camrunning);

          Here the camera thread continues running even after taking a frame. I am sure 'm missing something here. Sorry for bothering :) . -thanks

          PKNT

          M Offline
          M Offline
          Mark Salsbery
          wrote on last edited by
          #22

          I would use (and recommend) SetEvent() on auto-reset events and not PulseEvent(): getnewframe = ::CreateEvent(NULL, FALSE, FALSE, NULL); newframeevent = ::CreateEvent(NULL, FALSE, FALSE, NULL); I can't remember why but something about PulseEvent() is flaky/unreliable if I recall correctly (besides the fact that a thread has to be already waiting on it for it to work, which is bad for this case)....I just know I never use it. Compare that to SetEvent() - "The state of an auto-reset event object remains signaled until a single waiting thread is released". That's the behavior you'd want. Mark

          Mark Salsbery Microsoft MVP - Visual C++ :java:

          K 1 Reply Last reply
          0
          • M Mark Salsbery

            I would use (and recommend) SetEvent() on auto-reset events and not PulseEvent(): getnewframe = ::CreateEvent(NULL, FALSE, FALSE, NULL); newframeevent = ::CreateEvent(NULL, FALSE, FALSE, NULL); I can't remember why but something about PulseEvent() is flaky/unreliable if I recall correctly (besides the fact that a thread has to be already waiting on it for it to work, which is bad for this case)....I just know I never use it. Compare that to SetEvent() - "The state of an auto-reset event object remains signaled until a single waiting thread is released". That's the behavior you'd want. Mark

            Mark Salsbery Microsoft MVP - Visual C++ :java:

            K Offline
            K Offline
            Kiran Satish
            wrote on last edited by
            #23

            I tired to implement using SetEvent, but it still deadlocks, as I dont see any processor activity at all and just a busy mouse icon on the application interface. Here is how I did it - I defined the event handles at the start of the application in your way rather than using CEvent objects like I did before

            getnewframe = ::CreateEvent(NULL, FALSE, FALSE, NULL);
            newframeevent = ::CreateEvent(NULL, FALSE, FALSE, NULL);

            when the user clicks snapshot, I call a function (snapshot)

            snapshot(exposure)
            {
            set camera exposure
            start snapshotthread if not running
            SetEvent(getnewframe)
            ::WaitForSingleObject(waitfornewframe, INFINITE);
            display the frame
            }
            .
            .
            .
            camthread
            {
            do
            {
            ::WaitForSingleObject(getnewframe, INFINITE);
            take a 20ms snapshot
            SetEvent(waitfornewframe);
            }while(camrunning)
            }

            I still dont get where I am doing wrong :confused:. I even tried using a while loop in snapshot function and using a 1ms timeout value for WaitForSingleObject and checking for WAIT_OBJECT_0.

            PKNT

            M 1 Reply Last reply
            0
            • K Kiran Satish

              I tired to implement using SetEvent, but it still deadlocks, as I dont see any processor activity at all and just a busy mouse icon on the application interface. Here is how I did it - I defined the event handles at the start of the application in your way rather than using CEvent objects like I did before

              getnewframe = ::CreateEvent(NULL, FALSE, FALSE, NULL);
              newframeevent = ::CreateEvent(NULL, FALSE, FALSE, NULL);

              when the user clicks snapshot, I call a function (snapshot)

              snapshot(exposure)
              {
              set camera exposure
              start snapshotthread if not running
              SetEvent(getnewframe)
              ::WaitForSingleObject(waitfornewframe, INFINITE);
              display the frame
              }
              .
              .
              .
              camthread
              {
              do
              {
              ::WaitForSingleObject(getnewframe, INFINITE);
              take a 20ms snapshot
              SetEvent(waitfornewframe);
              }while(camrunning)
              }

              I still dont get where I am doing wrong :confused:. I even tried using a while loop in snapshot function and using a 1ms timeout value for WaitForSingleObject and checking for WAIT_OBJECT_0.

              PKNT

              M Offline
              M Offline
              Mark Salsbery
              wrote on last edited by
              #24

              I'm not seeing a deadlock situation in the pseudo code... If you run it in the debugger and break, are both threads sitting in the Wait function? If so, why?

              Mark Salsbery Microsoft MVP - Visual C++ :java:

              K 1 Reply Last reply
              0
              • M Mark Salsbery

                I'm not seeing a deadlock situation in the pseudo code... If you run it in the debugger and break, are both threads sitting in the Wait function? If so, why?

                Mark Salsbery Microsoft MVP - Visual C++ :java:

                K Offline
                K Offline
                Kiran Satish
                wrote on last edited by
                #25

                Here is what happening in debug more

                snapshot(exposure)
                {
                set camera exposure
                start snapshotthread if not running
                SetEvent(getnewframe)
                ::WaitForSingleObject(waitfornewframe, INFINITE); -- set breakpoint(1)
                display the frame
                }
                .
                .
                .
                camthread
                {
                do
                {
                dummy variable -- set breakpoint(2)
                ::WaitForSingleObject(getnewframe, INFINITE);
                take a 20ms snapshot
                SetEvent(waitfornewframe);
                }while(camrunning)
                }

                when I hit snapshot button, the program stops at breakpoint(1) and then goes to breakpoint(2) and thats it from there it does nothing while the C++ interface shows as the program is in [run] mode. From the definitions of SetEvent and WaitForSingleObject I too dont see any thing wrong here. Do they need to be in actual two different threads, I dont think thats the case, interesting!

                PKNT

                M 1 Reply Last reply
                0
                • K Kiran Satish

                  Here is what happening in debug more

                  snapshot(exposure)
                  {
                  set camera exposure
                  start snapshotthread if not running
                  SetEvent(getnewframe)
                  ::WaitForSingleObject(waitfornewframe, INFINITE); -- set breakpoint(1)
                  display the frame
                  }
                  .
                  .
                  .
                  camthread
                  {
                  do
                  {
                  dummy variable -- set breakpoint(2)
                  ::WaitForSingleObject(getnewframe, INFINITE);
                  take a 20ms snapshot
                  SetEvent(waitfornewframe);
                  }while(camrunning)
                  }

                  when I hit snapshot button, the program stops at breakpoint(1) and then goes to breakpoint(2) and thats it from there it does nothing while the C++ interface shows as the program is in [run] mode. From the definitions of SetEvent and WaitForSingleObject I too dont see any thing wrong here. Do they need to be in actual two different threads, I dont think thats the case, interesting!

                  PKNT

                  M Offline
                  M Offline
                  Mark Salsbery
                  wrote on last edited by
                  #26

                  hmm the only reason I see that could happen is if "take a 20ms snapshot" never returns so the waitfornewframe event gets set.

                  Mark Salsbery Microsoft MVP - Visual C++ :java:

                  K 3 Replies Last reply
                  0
                  • M Mark Salsbery

                    hmm the only reason I see that could happen is if "take a 20ms snapshot" never returns so the waitfornewframe event gets set.

                    Mark Salsbery Microsoft MVP - Visual C++ :java:

                    K Offline
                    K Offline
                    Kiran Satish
                    wrote on last edited by
                    #27

                    I even tired that too by commenting it out, but it does the same. will keep tryin different ways and see. Do you think I may need to define those event handles in CMutex objects :~ .

                    PKNT

                    M 1 Reply Last reply
                    0
                    • M Mark Salsbery

                      hmm the only reason I see that could happen is if "take a 20ms snapshot" never returns so the waitfornewframe event gets set.

                      Mark Salsbery Microsoft MVP - Visual C++ :java:

                      K Offline
                      K Offline
                      Kiran Satish
                      wrote on last edited by
                      #28

                      does it matter how I am defining my thread?? I am using DWORD WINAPI camclass::camthread(LPVOID) form.

                      PKNT

                      M 1 Reply Last reply
                      0
                      • K Kiran Satish

                        I even tired that too by commenting it out, but it does the same. will keep tryin different ways and see. Do you think I may need to define those event handles in CMutex objects :~ .

                        PKNT

                        M Offline
                        M Offline
                        Mark Salsbery
                        wrote on last edited by
                        #29

                        Kiran Satish wrote:

                        Do you think I may need to define those event handles in CMutex objects

                        No that's a different type of synchronization object for mutual exclusion.

                        Mark Salsbery Microsoft MVP - Visual C++ :java:

                        1 Reply Last reply
                        0
                        • K Kiran Satish

                          does it matter how I am defining my thread?? I am using DWORD WINAPI camclass::camthread(LPVOID) form.

                          PKNT

                          M Offline
                          M Offline
                          Mark Salsbery
                          wrote on last edited by
                          #30

                          How are you creating your threads? If you're using MFC and using MFC class objects in your threads you should be using AfxBeginThread(), and the prototype for the thread proc is UINT __cdecl ThreadProc(LPVOID pParam); If you're not using MFC but using CRT functions anywhere in your threads (including new/delete!) then you should be using _beginthread() or _beginthreadex(), and the prototype for the thread proc is unsigned __stdcall ThreadProc(void *lpParameter); For a pure C/C++ thread on Windows which doesn't use MFC or the CRT, you can use ::CreateThread(), and the prototype for the thread proc is DWORD WINAPI ThreadProc(LPVOID lpParameter); For MFC and/or CRT, make sure you're linking to the multithread version of those libraries.

                          Mark Salsbery Microsoft MVP - Visual C++ :java:

                          1 Reply Last reply
                          0
                          • M Mark Salsbery

                            hmm the only reason I see that could happen is if "take a 20ms snapshot" never returns so the waitfornewframe event gets set.

                            Mark Salsbery Microsoft MVP - Visual C++ :java:

                            K Offline
                            K Offline
                            Kiran Satish
                            wrote on last edited by
                            #31

                            I got it running. Unfortunately it doesnt run when I do it the way we discussed earlier, but when I run it in two different threads it works like it should. I am not sure why it did like tht before, but it doesnt work when I have it in between a function and thread.

                            PKNT

                            M 1 Reply Last reply
                            0
                            • K Kiran Satish

                              I got it running. Unfortunately it doesnt run when I do it the way we discussed earlier, but when I run it in two different threads it works like it should. I am not sure why it did like tht before, but it doesnt work when I have it in between a function and thread.

                              PKNT

                              M Offline
                              M Offline
                              Mark Salsbery
                              wrote on last edited by
                              #32

                              I always thought it was two threads!

                              Mark Salsbery Microsoft MVP - Visual C++ :java:

                              K 1 Reply Last reply
                              0
                              • M Mark Salsbery

                                I always thought it was two threads!

                                Mark Salsbery Microsoft MVP - Visual C++ :java:

                                K Offline
                                K Offline
                                Kiran Satish
                                wrote on last edited by
                                #33

                                Sorry abt that confusion... maybe I wasnt clear enough.... :), anyway now I know how to use Events in an efficent way... thanks for your help and patience on this...

                                PKNT

                                M 1 Reply Last reply
                                0
                                • K Kiran Satish

                                  Sorry abt that confusion... maybe I wasnt clear enough.... :), anyway now I know how to use Events in an efficent way... thanks for your help and patience on this...

                                  PKNT

                                  M Offline
                                  M Offline
                                  Mark Salsbery
                                  wrote on last edited by
                                  #34

                                  Kiran Satish wrote:

                                  maybe I wasnt clear enough

                                  I think I just assumed :) Glad you got it working! Cheers, mark

                                  Mark Salsbery Microsoft MVP - Visual C++ :java:

                                  1 Reply Last reply
                                  0
                                  • M Mark Salsbery

                                    Cool good luck! Keep in mind: Locking is bad - eliminate it if possible - only lock for as long as necessary, and there's lots of other threads running in the system to mess with your timing :) Mark

                                    Mark Salsbery Microsoft MVP - Visual C++ :java:

                                    K Offline
                                    K Offline
                                    Kiran Satish
                                    wrote on last edited by
                                    #35

                                    I am back with another issue in this application :) , saving frames in real-time without dropping and in the same order. I tried using BipBuffer[^]. This is how I implemented, the actual thread keeps running and signals an event to 'SaveImage' thread for every ~20msec where it appends the image data to BipBuffer memory while another thread keeps running all the time saving images from BipBuffer until the BipBuffer memory is NULL. I am allocating 64x(512x512)bytes of memory to BipBuffer. While running like this, the close loop (main thread) starts off at 50Hz and after a while (like 6-7 sec) depending on the size of BipBuffer memory, it slows down to like 39Hz and then goes back to 50Hz slowly. Is there any other way I can save all the images in real-time at 50Hz with out dropping the actual frames coming in from the camera (i.e I have ~17msec to save a particular frame)?? -thanks

                                    PKNT

                                    M 1 Reply Last reply
                                    0
                                    • K Kiran Satish

                                      I am back with another issue in this application :) , saving frames in real-time without dropping and in the same order. I tried using BipBuffer[^]. This is how I implemented, the actual thread keeps running and signals an event to 'SaveImage' thread for every ~20msec where it appends the image data to BipBuffer memory while another thread keeps running all the time saving images from BipBuffer until the BipBuffer memory is NULL. I am allocating 64x(512x512)bytes of memory to BipBuffer. While running like this, the close loop (main thread) starts off at 50Hz and after a while (like 6-7 sec) depending on the size of BipBuffer memory, it slows down to like 39Hz and then goes back to 50Hz slowly. Is there any other way I can save all the images in real-time at 50Hz with out dropping the actual frames coming in from the camera (i.e I have ~17msec to save a particular frame)?? -thanks

                                      PKNT

                                      M Offline
                                      M Offline
                                      Mark Salsbery
                                      wrote on last edited by
                                      #36

                                      Kiran Satish wrote:

                                      I am allocating 64x(512x512)bytes of memory to BipBuffer

                                      Are you sure that's a big enough buffer? If the data is 24bpp RGB, you may want 64x(512x512x3). Which thread is slowing down? Are you locking something (or staying in a critical section) too long? Mark

                                      Mark Salsbery Microsoft MVP - Visual C++ :java:

                                      K 2 Replies Last reply
                                      0
                                      • M Mark Salsbery

                                        Kiran Satish wrote:

                                        I am allocating 64x(512x512)bytes of memory to BipBuffer

                                        Are you sure that's a big enough buffer? If the data is 24bpp RGB, you may want 64x(512x512x3). Which thread is slowing down? Are you locking something (or staying in a critical section) too long? Mark

                                        Mark Salsbery Microsoft MVP - Visual C++ :java:

                                        K Offline
                                        K Offline
                                        Kiran Satish
                                        wrote on last edited by
                                        #37

                                        My images are only 8bpp(0-255) and I use unsigned char pointer for image data. I am not sure which thread is slowing down and as fas as I know I dont have any critical sections. Here is the order- BipBuffer ImageBuffer; ImageBuffer.AllocateBuffer(128*m_FrameBufferSize) //m_FrameBufferSize = 512x512 -Main Thread (camera thread)- // this controls the processing thread while (camthread) take image (~20.5msec) copy image data into shared buffer set event to processing thread -Processing thread- while (processing thread) wait for event from camera copy image data from shared buffer to processing buffer if(saveimage) copy image data from shared buffer to buffer for saving image Set event to save image thread do the processing on image data in processing buffer Update displays for results -Save Image thread- BYTE* pData wait for save image event pData = ImageBuffer.Reserve(m_FrameBufferSize, iResult) memcpy(pData, m_pImageBuffer, iResult) ImageBuffer.Commit(iResult) //iResult will be equal to m_FrameBufferSize -Store Image thread- //this thread runs continuously until BipBuffer == NULL while ((pData = ImageBuffer.GetContiguousBlock(iResult)) != NULL){ create filename write image data to a file (I tried writing in two ways to see if there will be any difference in speed, one as a tiff format and also as a binary file) ImageBuffer.DecommitBlock(iResult)} I think I might just use a standard circular buffer of my own rather than BipBuffer as I see there is something going on when using it. When I run the program loop for 15sec, the number of images being stored are increasing from one run to another. Hope I am clear :) . If I comment out writing image data to a file in store image thread, everything runs fine at desired speed. -thanks

                                        PKNT

                                        M S 2 Replies Last reply
                                        0
                                        • M Mark Salsbery

                                          Kiran Satish wrote:

                                          I am allocating 64x(512x512)bytes of memory to BipBuffer

                                          Are you sure that's a big enough buffer? If the data is 24bpp RGB, you may want 64x(512x512x3). Which thread is slowing down? Are you locking something (or staying in a critical section) too long? Mark

                                          Mark Salsbery Microsoft MVP - Visual C++ :java:

                                          K Offline
                                          K Offline
                                          Kiran Satish
                                          wrote on last edited by
                                          #38

                                          Also I did a test with 5sec, the camera is indeed getting all the frames (5000/20.5 = ~243) constantly, while using BipBuffer and saving the images, for first run I get ~206 saved, second run ~213, third run ~224 etc, which I think is overwriting the frame data in the buffer, but the difference in the numbers doesnt explain anything to me. There should be a pretty simple way to write data to HDD at 50frames/sec (at 512x512bytes/frame), which I dont think is that much when you consider real-time applications :confused:.

                                          PKNT

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups