8 years, 6 months ago.

Start thread inside timeout

It seems impossible to start a thread when that thread is launched via a timeout. Is there a way to accomplish the same functionality?

Question relating to:

1 Answer

8 years, 6 months ago.

I think if you start it properly using 'new' it works, but in general I wouldn't advice it to construct anything in an interrupt handler. I would just set a variable or use one of the RTOS functions for this (a Signal or something similar), and then in your main thread construct a new thread once that variable/Signal is set.

Thanks for the answer. Indeed I have thought of polling a flag and constructing the thread when the flag has changed, however I was hoping for an event driven solution.

Allocating memory for a thread reference using 'new' does indeed work inside of the timeout, however once the timeout exits, I lose reference to the thread. Allocating a thread reference globally allows me to reference the thread outside of the timeout function (memory is on the heap) but this method causes the above behavior in the original post. Am I thinking about it wrong?

Thanks

posted by Ethan P 17 Sep 2015

If you use new, you need something to give the pointer to the thread to other locations. That could be a global pointer you set, or for example a function you use to send the pointer to wherever it is used.

What do you use now? If you make a new Thread without the 'new' keyword, but just the 'normal' way, it will be destroyed as soon as it leaves scope, which is as soon as the interrupt ends. Similar to if you make a new integer in your interrupt handler: As soon as the interrupt handler is finished it is gone.

posted by Erik - 17 Sep 2015

Thanks Erik.

I was using global 'osThreadId' variables to keep references to the threads that were created on the stack (without using 'new') inside the timeouts.

For testing, I have switched to creating threads by allocating memory on the heap using 'new' keyword when flags are set by the timeout functions. The main while(1) loop looks as follows:

globally:

Thread *gps_view_switcher_thread
Thread *gps_write_thread

within main while(1) loop:

        if(flag_start_gps_thread){
            gps_write_thread = new Thread(gps_write);
            flag_start_gps_thread = false;
        }
        if(flag_start_gps_alt_view){
            gps_view_switcher_thread = new Thread(gps_view_switcher);
            flag_start_gps_alt_view = false;
        }
        if(kill_gps_write_thread){
            int gps_thread_state = gps_write_thread->get_state();
            if(gps_thread_state != Thread::Inactive){
                gps_write_thread->terminate();
                delete gps_write_thread;
            }
            
            kill_gps_write_thread = false;
        }
        if(kill_gps_view_switcher_thread){
            int gps_view_switcher_state = gps_view_switcher_thread->get_state();
            if(gps_view_switcher_state != Thread::Inactive) {
                gps_view_switcher_thread->terminate();
                delete gps_view_switcher_thread;
            }
            
            kill_gps_view_switcher_thread = false;
        } 

The above code simply starts a thread when one of the first two above flags are started and kills it in the same way.

The problem is that this implementation will lock up after a few starts and stops of either thread. The threads never run at the same time and any time one is started, the other is killed. Each thread should be able to start and be terminated an unlimited number of times but after 3 or 4 times the code will lock up.

E.g. on a button press, i will raise the 'kill_gps_view_switcher_thread' flag and then raise the 'flag_start_gps_thread'.

posted by Ethan P 23 Sep 2015