[Insight-developers] multithreading update w/example code

Miller, James V (Research) millerjv@crd.ge.com
Tue, 23 Apr 2002 08:48:15 -0400


Not using the Win32OutputWindow is definately an option.  We probably
haven't seen this problem before because I usually use a text output
window (or a file output window) so that I can see my debug statements
after the program finishes.

But this just fixes the "symptom".  The problem is that any threaded 
code has to be careful not to use a Win32OutputWindow.

A solution may be to have the Win32OutputWindow create a separate thread
to run in.  By default (or practise, I can't determine which) the thread
that creates a window also manages its event loop.  So the Win32OutputWindow
could create a thread, create its window, and start an event loop in that thread
for that window.  Then other threads would use PostMessage() instead of SendMessage()
to send output to that window.

I am not quite sure how to create this "user interface" thread and event loop
in Win32. Most of the docs I am finding on the web are for MFC.



-----Original Message-----
From: William A. Hoffman [mailto:bill.hoffman@kitware.com]
Sent: Monday, April 22, 2002 9:56 PM
To: Miller, James V (Research); Miller, James V (Research); 'Damion
Shelton'; insight-developers@public.kitware.com
Subject: RE: [Insight-developers] multithreading update w/example code


Why not change the Win32OutputWindow to a text output window.
See itkThresholdImageFilterTest.cxx for an example.

-Bill

At 03:43 PM 4/22/2002 -0400, Miller, James V (Research) wrote:
>I think I located the Win32OutputWindow problem.
>
>Here is my current best guess.
>
>When multiple threads are being used, we create N-1 new threads
>and use the main thread as the Nth thread to split the job across.
>The Win32OutputWindow calls SendMessage() which sends a message
>to the "main" thread and waits for its response.
>
>So on a 2 processor system, the second thread sends a debug message
>to the output window and waits for it to return.  The main thread
>also sends a debug message to the output window and waits for it to
>return.  The problem is that the main thread is too busy waiting
>for it to handle the message to handle the message.
>
>I think we might be able to use PostMessage instead of SendMessage
>or I can change the threading code so it always starts N threads and
>does not use the main thread.  The latter will require figuring out
>how to get the multi-threader code to handle the event loop AND
>wait for the threads to finish.
>
>
>-----Original Message-----
>From: Miller, James V (Research)
>Sent: Monday, April 22, 2002 3:33 PM
>To: 'Damion Shelton'; insight-developers@public.kitware.com
>Subject: RE: [Insight-developers] multithreading update w/example code
>
>
>I was able to duplicate the problem on a dual processor
>WinNT system.
>
>Here's the rub: the Win32OutputWindow is deadlocking when
>multiple threads write at the same time.  This is occuring
>because you have DebugOn() on the GradientImageFilter.
>
>Turning DebugOff() on the GradientImageFilter and the program
>works fine for me.
>
>
>
>-----Original Message-----
>From: Damion Shelton [mailto:dmshelto@andrew.cmu.edu]
>Sent: Monday, April 22, 2002 1:47 PM
>To: insight-developers@public.kitware.com
>Subject: [Insight-developers] multithreading update w/example code
>
>
>Hi,
>
>In our continuing efforts to track down the multithreading weirdness with a
>dual Athlon XP machine, we've narrowed our test code down to the following
>example, which does not include any of our own code.
>
>Based on the debug output, it looks like it hangs in the gradient filter.
>By "hangs", we mean that the processor usage drops to 0% and the program
>never returns.
>
>Any ideas, please let us know. We can check this in as
>"itkMultithreadingTest" or something similar if that would be a help in
>diagnosing the problem.
>
>Thanks,
>Damion and Wilson
>
>------
>
>#include <stdio.h>
>
>// Basic ITK stuff
>#include "itkSize.h"
>#include "itkIndex.h"
>#include "itkImage.h"
>#include "itkImageRegionIterator.h"
>#include "itkPoint.h"
>#include "itkShrinkImageFilter.h"
>#include "itkGradientImageFilter.h"
>
>// Image file reading
>#include "itkImageFileReader.h"
>#include "itkMetaImageIOFactory.h"
>
>// Main for testing BloxImage/BloxPixel storage
>void main()
>{
>   const unsigned int dim = 3;
>
>   // Image typedef
>   typedef itk::Image< unsigned char, dim > TImageType;
>   typedef itk::ImageFileReader<TImageType> ImageFileReaderType;
>
>   // The input file reader
>   ImageFileReaderType::Pointer reader;
>
>   //set up the reader and register the possible types
>   reader = ImageFileReaderType::New();
>   reader->DebugOn();
>   itk::MetaImageIOFactory::RegisterOneFactory();
>   reader->SetFileName("d:/brainweb/brainweb1.mha");
>   reader->GetOutput()->SetRequestedRegionToLargestPossibleRegion();
>   reader->Update();
>
>   // Shrink by a factor of 2
>   typedef itk::ShrinkImageFilter<TImageType, TImageType> ShrinkType;
>   ShrinkType::Pointer pShrink = ShrinkType::New();
>   pShrink->SetShrinkFactors(2);
>   pShrink->SetInput( reader->GetOutput() );
>
>   // Create a gradient filter
>   typedef itk::GradientImageFilter<TImageType> TGradientFilter;
>   TGradientFilter::Pointer gradFilter = TGradientFilter::New();
>   gradFilter->DebugOn();
>   gradFilter->SetInput( pShrink->GetOutput() );
>
>   // Run the whole pipeline
>   gradFilter->Update();
>
>   // Get the output of the pipeline
>   TGradientFilter::OutputImageType::Pointer gradOutput =
>gradFilter->GetOutput();
>}
>_______________________________________________
>Insight-developers mailing list
>Insight-developers@public.kitware.com
>http://public.kitware.com/mailman/listinfo/insight-developers
>_______________________________________________
>Insight-developers mailing list
>Insight-developers@public.kitware.com
>http://public.kitware.com/mailman/listinfo/insight-developers
>_______________________________________________
>Insight-developers mailing list
>Insight-developers@public.kitware.com
>http://public.kitware.com/mailman/listinfo/insight-developers