Ответ 1
Один из "правильных" способов сделать это - проверить функцию потока, если он kthread_should_stop
, и просто вернуться, если это нужно остановить.
Вам не нужно вызывать do_exit
, и если вы собираетесь kthread_stop
его из функции выхода из модуля, вы, вероятно, не должны.
Вы можете увидеть это, посмотрев документацию для kthread_create_on_node
в kernel/kthread.c
(извлечение из ядра Linux 3.3.1):
/**
* kthread_create_on_node - создать kthread.
* @threadfn: функция для запуска до signal_pending (текущий).
* @data: данные ptr для @threadfn.
* @node: номер памяти node.
* @namefmt: имя файла printf для потока.
*
* Описание: эта вспомогательная функция создает и называет ядро
* нить. Поток будет остановлен: используйте wake_up_process(), чтобы начать работу * Это. См. Также kthread_run().
*
* Если поток будет привязан к определенному процессору, дайте его node
* в @node, чтобы получить NUMA-сродство к стекю kthread, или дать -1.
* Когда woken, поток будет запускать @threadfn() с @data как его * аргумент. @threadfn() может либо вызвать do_exit() напрямую, если это
* автономный поток, для которого никто не будет называть kthread_stop(), или
* return, когда 'kthread_should_stop()' истинно (что означает * kthread_stop() был вызван). Возвращаемое значение должно быть равно нулю * или отрицательный номер ошибки; он будет передан kthread_stop().
*
* Возвращает task_struct или ERR_PTR (-ENOMEM).
*/
Для kthread_stop
присутствует комментарий "сопоставление":
Если threadfn() может вызывать do_exit(), , вызывающий должен убедиться, что task_struct не может уйти.
(И я не уверен, как вы это делаете - возможно, держась за struct_task
с get_task_struct
.)
Если вы пройдете путь создания потока, вы получите что-то вроде:
kthread_create // macro in kthread.h
-> kthread_create_on_node // in kthead.c
-> adds your thread request to kthread_create_list
-> wakes up the kthreadd_task
kthreadd_task
устанавливается в init/main.c
в reset_init
. Он выполняет функцию kthreadd
(от kthread.c
)
kthreadd // all in kthread.c
-> create_kthread
-> kernel_thread(kthread, your_kthread_create_info, ...)
И сама функция kthread
делает:
kthread
-> initialization stuff
-> schedule() // allows you to cancel the thread before it actually started
-> if (!should_stop)
-> ret = your_thread_function()
-> do_exit(ret)
... Итак, если your_thread_function
просто возвращается, do_exit
будет вызываться с его возвращаемым значением. Не нужно делать это самостоятельно.