Concepts of cooperate multi threading, co-rutines etc. aren't limited to user space.
Actually they out date the whole "async" movement or whatever you want to call it.
Also the article is about user-space threads, i.e. OS threads, not kernel-space threads (which use kthread_* not pthread_* and kthreads stopping does work by setting a flag to indicate it's supposed to stop, wakes the thread and then waits for exit. I.e. it works much more close to the `if(stop) exit` example then any signal usage.
The pthread API, defined by POSIX, and referred to in TFA's title as "linux threads", concerns kernel threads. Pthreads does not provide user-space threads in any implementation I am aware of, and is not intended to (though it likely could be done). The API is intended to allow a process to have multiple execution contexts that can be scheduled by the kernel independently.
I think you have a very strange definition of "user-space", "kernel-space".
kernel space is what runs _in_ the kernel, it doesn't involve pthreads (on any OS) and uses kthreads (on Linux).
POSIX threads are user space threads. It doesn't matter that they are scheduled by the kernel, that is the norm for threads in user space. Also know as OS threads.
What you probably mean with user-space threads are green threads. Which are build on one or more OS threads but have an additional scheduling layer which can schedule multiple green threads on one OS thread using some form of multiplexing scheme.
Actually they out date the whole "async" movement or whatever you want to call it.
Also the article is about user-space threads, i.e. OS threads, not kernel-space threads (which use kthread_* not pthread_* and kthreads stopping does work by setting a flag to indicate it's supposed to stop, wakes the thread and then waits for exit. I.e. it works much more close to the `if(stop) exit` example then any signal usage.