Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Main Thread Hangs


  • Please log in to reply
7 replies to this topic

#1 banalogic

banalogic

    New Member

  • Members
  • Pip
  • 7 posts

Posted 28 June 2013 - 01:53 PM

I discovered an interesting issue while experimenting with Threading.

 

I have the following Main Program:

 

        public static void Main()
        {
            ToogleOutput output0 = new ToogleOutput(Pins.ONBOARD_LED);
            ToogleOutput output1 = new ToogleOutput(Pins.GPIO_PIN_A0);
            ToogleOutput output2 = new ToogleOutput(Pins.GPIO_PIN_A1);
 
            Thread thread1 = new Thread(output1.Flash);
            Thread thread2 = new Thread(output2.Flash);
 
            thread1.Start();
            thread2.Start();
 
            output0.Flash();
        }

 

 

ToggleOutput is a simple class I made to toggle an output pin periodically. I tried 2 different methods to toggle:

 

Method 1 uses Thread.Sleep:

                while (true)
                {
                    Thread.Sleep(500);
                    toogleState = !toogleState;
                    port.Write(toogleState);
                }

 

 

Method 2 uses an infinitely loop with a counter. The pin toggles every 3000 iterations:

 

                int counter = 0;
                while (true)
                {
                    counter++;
 
                    if (counter > 3000)
                    {
                        counter = 0;
                        toogleState = !toogleState;
                        port.Write(toogleState);
                    }
                }
 
I connected two LEDs to pin A0 and A1.  The expected behavior is the onboard LED and the two attached LEDs will flash periodically.
 

If method 1 is used, everything works fine.

 

If method 2 is used, The onboard LED will flash for a second or so, then it will stop flashing, while my LEDs connected to A0 and A1 will continue to flash. The observation suggests the main thread will run for a second or so, then the scheduler will give execution cycles to thread 1 and 2, but the main thread was never given any processing cycle back to execute its operation. The workaround is creating a 3rd thread to flash the onboard LED, and in main, put Thread.CurrentThread.Suspend() to suspend the main thread.

 

Interestingly, if I run the program using method 2 through a debugger with Visual Studio, then everything works fine.

 

Full test program is attached.

Attached Files



#2 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 28 June 2013 - 02:35 PM

The scheduler may have problems switching between threads since they are all running in tight loops. Try yielding briefly in the loop by calling Thread.Sleep(1) once in a while.



#3 Nevyn

Nevyn

    Advanced Member

  • Members
  • PipPipPip
  • 1072 posts
  • LocationNorth Yorkshire, UK

Posted 28 June 2013 - 02:37 PM

I think the problem is that your main program loop has exited.  Try using a Thread.Sleep with an infinite timeout just before the end of Main.

 

Regards,

Mark


To be or not to be = 0xFF

 

Blogging about Netduino, .NET, STM8S and STM32 and generally waffling on about life

Follow @nevynuk on Twitter


#4 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 28 June 2013 - 11:56 PM

Since the last thing of Main() is to call output0.Flash() which enters an infinite loop, I don't think Main() ever returns, at least not according to the Program.cs attached where ToggleMethod is set to LoopIteration for all instances of the ToggleOutput class by a static member of the Program class.

#5 banalogic

banalogic

    New Member

  • Members
  • Pip
  • 7 posts

Posted 29 June 2013 - 03:52 AM

Hanzibal is right. Main() calls an infinite loop and never exited. The scheduler just never returned to the main thread. The interesting thing is the other threads ran fine. If I move output0.Flash() to a third thread then all the lights flashes simultaneously. So how is the Main Thread different from other threads? Also if I run the code in debug under VS then it behaves properly, despite the lights flash much slower because of the debugger communication. Is this a SDK, firmware or .NET MF defect? 

 

The reason I do not want to put a Thread.Sleep() is I need to monitor the input pins as frequently as possible. My actual project currently only runs under the main thread and the main loop iterates 3 times a ms. As I am adding more functionality to the program multi-threaded application will become much cleaner and easier to maintain, but I can't afford to put a 1ms sleep without changing a lot of code. Is there a way to sleep less, i.e. 1/2 ms?

 

I also wonder how much performance overhead does the thread scheduler take? i.e If I put 2 loop counters on 2 threads and add the counters together (a+B), vs. one thread with loop counter c.  What is the ratio of (a+B) : c?  I will give it a try when I have time and report.



#6 NooM

NooM

    Advanced Member

  • Members
  • PipPipPip
  • 490 posts
  • LocationAustria

Posted 29 June 2013 - 11:10 AM

let me know the results. i bet its way slower, at least 20%

do it like that: first count a variable up for one second in your main thread, than print it.

than count 2 variables up, each in a seperate thread (also one second total, not each thread a second :D ) .. add it and print it :D

 

iam with nevyn, your main problem is the end of your main thread, in your code there is no loop.

 

or what does output0.Flash(); do ?

add a: thread.sleep(timeout.infinite); after that.



#7 Anshul

Anshul

    Advanced Member

  • Members
  • PipPipPip
  • 50 posts

Posted 08 July 2013 - 05:56 PM

 

iam with nevyn, your main problem is the end of your main thread, in your code there is no loop.

 

or what does output0.Flash(); do ?

 

 

The main thread doesn't end, it goes in an infinite loop because output0.Flash() does the same thing as the other threads, either method 1 or method 2 whichever OP is using.

 

 

 

@banalogic: Have you figured out why the main thread does not get an execution cycles? I've noticed that when my main thread goes into a tight infinite loop (tight = no Thread.Sleep(n) in the loop), it doesn't even respond to the Visual Studio debugger. Only option is to erase the program by going into bootloader mode and then reconnect it to the computer.



#8 ziggurat29

ziggurat29

    Advanced Member

  • Members
  • PipPipPip
  • 244 posts

Posted 08 July 2013 - 07:49 PM

it gets some execution before locking up.  A couple things I observed:

*  connecting a scope to the onboard LED

  *  always flashes 8 times before 'locking up' (with code as above)

  *  this in my limited manually executed tests of maybe 20 attempts (tedious!)

*  if the code is running not-locked-up (because of debugger connection)

  *  you can detach the debugger (with the 'stop' button)

  *  even close VS

  *  continues to run

and I'm sure everyone has noticed that the flashing of the onboard led is much much faster with no debugger (before it locks up).

I did verify that all the threads are running at priority 'normal'  (although even if they were at different priorities, that should not starve a thread, and I have coincidentally verified that in a separate test in the past, but not relative to the main thread).

 

Anyway, I think for most folks the underlying problem is masked, because either they are sleep'ing at some point, or do a sleep(infinite) on the main thread, and do all their stuff in the workers.






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.