How can I terminate a thread that is in a waiting state?

Here it is suggested to gracefully terminate a thread by sending it a notification of any kind. But how can I terminate a thread that is in a waiting state with K_FOREVER and that I know will never unblock, without using k_thread_abort()? An example of a thread to terminate could be the following:

void Foo_Thread( void )
{
    fifo_ble_communication_item_t *fifoItem;

    for ( ;; )
    {
        fifoItem = k_fifo_get( &fooFifo, K_FOREVER );
        
        /* use fifoItem data */
    }
}

  • Hmm, 

    Something is not right, 

    But how can I terminate a thread that is in a waiting state with K_FOREVER and that I know will never unblock

    A thread that have reached to this point seems like a mistake and should have aborted if it went into that state knowingly. If that thread went into this state due to unhandled conditions, and another thread can detect this, then there are many ways to do this. Use flags or timeouts 

    For example using a flag like terminate_thread_flag

    static volatile bool terminate_thread_flag = false;
    
    void main(void)
    {
        k_tid_t thread_id = k_thread_create(..., Foo_Thread, ...);
    
        // wome work
        xxx_xxx
    
        // Notify the thread to terminate
        terminate_thread_flag = true;
    
    
    }

    and the thread that needs killing can have the flag checked in the start like below

    void Foo_Thread(void)
    {
        struct fifo_item *fifoItem;
    
        while (!terminate_thread_flag) {
        ...
        ...

  • The type of thread I used as an example remains indefinitely waiting for incoming data (in this case, via a FIFO). To terminate such a thread that is waiting for data that will no longer arrive, is it preferable to use a timeout like this:

    void Foo_Thread(void) {
        fifo_ble_communication_item_t *fifoItem;
    
        for (;;) {
            fifoItem = k_fifo_get(&fooFifo, K_MSEC(100));
            
            if (fifoItem != NULL) {
                /* use fifoItem data */
            } else if (terminate_thread_flag == true) {
                return;
            }
        }
    }

    Or k_thread_abort() without the timeout?

  • The concern with using timeout in fifo_get is that you count on getting a fifo item within 100 milliseconds else this thread will be killed. If that fits your design, that a delay of 100ms in getting a fifo item means you wont get it anymore then the above code looks right. Else I would use abort.

  • getting a fifo item within 100 milliseconds else this thread will be killed

    Why do you say that if I don't receive a FIFO object, the process gets killed? In my last example, if the timeout expires, the FIFO object will be NULL, and in that case, if the variable terminate_thread_flag has been set, then I terminate the process with a return. Otherwise, I restart the for loop.

  • You are right Andrea, the else if statement takes care of that. So flag seems to be a good choice ...

Related