Create a kernel thread:
Struct task_struct * kthread_create (INT (* threadfn) (void * data ),
Void * data, const char namefmt []);
Wake up the kernel thread (which can wake up all processes (threads )):
Wake_up_process (struct task_struct * k );
Create and run the kernel thread:
Struct task_struct * kthread_run (INT (* threadfn) (void * data ),
Void * data, const char namefmt []);
Notify kernel thread to stop:
Int kthread_stop (struct task_struct * k );
Returns the return value of the threadfn function. If K is not wake_up_process (K),-eintr is returned.
Does not force stop. If the kernel thread does not stop, it will always wait.
Check whether a stop signal is received:
Int kthread_should_stop (void );
Difference between kthread_create and kernel_thread
On the surface, these two functions are very similar, but their implementations are quite different.
Kthread_create is implemented through work_queue, and kernel_thread is implemented through do_fork.
Kernel thread can be created using kernel_thread. However, in the execution function, you must use daemonize to release resources and mount them to init. You also need to use completion to wait for the completion of this process.
Kthread_create is a positive creation function, which does not need to call daemonize. All created kernel threads are attached to the kthread.
You can call kernel_thread in a non-kernel thread, but the created thread must call daemonize (...) to release resources and become a real kernel thread.
# Include <Linux/kernel. h>
# Include <Linux/module. h>
Static int Noop (void * dummy)
{
Int I = 0;
Daemonize ("mythread ");
While (I ++ <5 ){
Printk ("Current-> MM = % P \ n", current-> mm );
Printk ("Current-> active_mm = % P \ n", current-> active_mm );
Set_current_state (task_interruptible );
Schedule_timeout (10 * Hz );
}
Return 0;
}
Static int test_init (void)
{
Kernel_thread (Noop, null, clone_kernel | sigchld );
Return 0;
}
Static void test_exit (void ){}
Module_init (test_init );
Module_exit (test_exit );
"Mythread" is the name given to this kernel thread, which can be viewed by PS-.
Schedule () is used for process scheduling. It can be understood as giving up CPU usage.
Kthread_create creation thread
1. Use kthread_create to create a thread:
Struct task_struct * kthread_create (INT (* threadfn) (void * data), void * data,
Const char * namefmt ,...);
This function can input a thread name in a certain format like printk.
After a thread is created, it does not run immediately. Instead, it needs to pass the task_struct pointer returned by kthread_create () to wake_up_process () and then run the thread through this function.
2. Of course, there is also a function to create and start a thread: kthread_run
Struct task_struct * kthread_run (INT (* threadfn) (void * data ),
Void * data,
Const char * namefmt ,...);
3. once started, the thread will continue to run unless the thread actively calls the do_exit function or other processes call the kthread_stop function to end the running of the thread.
Int kthread_stop (struct task_struct * thread );
Kthread_stop () sends a signal to the thread.
If a thread function is processing a very important task, it will not be interrupted. Of course, if a thread function never returns and does not check the signal, it will never stop.
Reference: Kernel threads made easy -- View plaincopy to clipboardprint?
# Include <Linux/kthread. h>
Static struct task_struct * _ task;
Static struct task_struct * _ task2;
Static struct task_struct * _ task3;
Static int thread_func (void * Data)
{
Int J, K;
Int timeout;
Wait_queue_head_t timeout_wq;
Static int I = 0;
I ++;
J = 0;
K = I;
Printk ("thread_func % d started \ n", I );
Init_waitqueue_head (& timeout_wq );
While (! Kthread_should_stop ())
{
Interruptible_sleep_on_timeout (& timeout_wq, Hz );
Printk ("[% d] sleeping .. % d \ n", K, J ++ );
}
Return 0;
}
Void my_start_thread (void)
{
// _ Task = kthread_create (thread_func, null, "thread_func2 ");
// Wake_up_process (_ task );
_ Task = kthread_run (thread_func, null, "thread_func2 ");
_ Task2 = kthread_run (thread_func, null, "thread_func2 ");
_ Task3 = kthread_run (thread_func, null, "thread_func2 ");
If (! Is_err (_ task ))
{
Printk ("kthread_create done \ n ");
}
Else
{
Printk ("kthread_create error \ n ");
}
}
Void my_end_thread (void)
{
Int ret = 0;
Ret = kthread_stop (_ task );
Printk ("End thread. ret = % d \ n", RET );
Ret = kthread_stop (_ task2 );
Printk ("End thread. ret = % d \ n", RET );
Ret = kthread_stop (_ task3 );
Printk ("End thread. ret = % d \ n", RET );
}
# Include <Linux/kthread. h>
Static struct task_struct * _ task;
Static struct task_struct * _ task2;
Static struct task_struct * _ task3;
Static int thread_func (void * Data)
{
Int J, K;
Int timeout;
Wait_queue_head_t timeout_wq;
Static int I = 0;
I ++;
J = 0;
K = I;
Printk ("thread_func % d started \ n", I );
Init_waitqueue_head (& timeout_wq );
While (! Kthread_should_stop ())
{
Interruptible_sleep_on_timeout (& timeout_wq, Hz );
Printk ("[% d] sleeping .. % d \ n", K, J ++ );
}
Return 0;
}
Void my_start_thread (void)
{
// _ Task = kthread_create (thread_func, null, "thread_func2 ");
// Wake_up_process (_ task );
_ Task = kthread_run (thread_func, null, "thread_func2 ");
_ Task2 = kthread_run (thread_func, null, "thread_func2 ");
_ Task3 = kthread_run (thread_func, null, "thread_func2 ");
If (! Is_err (_ task ))
{
Printk ("kthread_create done \ n ");
}
Else
{
Printk ("kthread_create error \ n ");
}
}
Void my_end_thread (void)
{
Int ret = 0;
Ret = kthread_stop (_ task );
Printk ("End thread. ret = % d \ n", RET );
Ret = kthread_stop (_ task2 );
Printk ("End thread. ret = % d \ n", RET );
Ret = kthread_stop (_ task3 );
Printk ("End thread. ret = % d \ n", RET );
} When kthread_stop is executed, the target thread must not exit; otherwise, oops will occur. The cause is easy to understand. When the target thread exits, its corresponding task structure becomes invalid. If kthread_stop references this invalid task structure, an error will occur. To avoid this problem, make sure that the thread does not exit, as shown in the Code: thread_func () {// do your work here // wait to exit while (! Thread_could_stop () {Wait () ;}} exit_code () {kthread_stop (_ task); // send a signal to the task to notify the task that it can exit} this exit mechanism is very gentle, everything is under the control of thread_func (). When a thread exits, it can release resources with ease, rather than being "stabbed" inexplicably ".