内核线程和普通的进程间的区别在于内核线程没有独立的地址空间,它只在 内核空间运行,从来不切换到用户空间去;并且和普通进程一样,可以被调度,也可以被抢占。
一 线程的创建
二 线程的退出
kthread_stop:设置线程的退出标记(线程函数内应用int kthread_should_stop(void)函数,当返回真时应退出函数),kthread_stop会一直等待至线程结束,线程结束前会发送完成结束给kthread_stop,如果直接使用do_exit直接退出线程那么kthread_stop不会收到完成信号将一直等待下去。如果线程已经退出那么kthread_stop会先设置退出标记再唤醒一下thread,唤醒线程后会判断退出标记因此设定的处理函数不会被调用。如果线程已经被唤醒并已经退出那么kthread_stop会一直等待。
三 源码分析 这里使用的内核版本是2.6.21.5
3.2 kthread_create创建线程
上面看到创建工作是在keventd_create_kthread函数里,那么看下keventd_create_kthread函数
3.3 kthread_stop线程的停止
这个函数在kthread_stop()被调用后返回真,当返回为真时你的处理函数要返回,返回值会通过kthread_stop()返回。所以你的处理函数应该有判断kthread_should_stop然后退出的代码。
注意如果调用了kthread_stop你的处理函数不能调用do_exit(),函数返回你处理函数的返回值,如果创建的线程还没调用过wake_up_process()那么会返回-EINTR . 四 测试代码
通过几个函数可以很容易的创建内核线程,但线程创建出来之后我们更关注的是有多线程带来的并发和竞争问题。并发的管理是操作系统编程的核心问题之一,引起的错误是一些最易出现又最难发现的问题.
一 线程的创建
可见kthread_run是在调用了kthread_create后执行了wake_up_process.
在非内核线程中调用kernel_thread,必须在调用daemonize(...)来释放资源,成为真正的内核线程,kthread_create实际调用kernel_thread但是内部已经做了处理,不需要自己调用daemonize。
二 线程的退出
kthread_stop:设置线程的退出标记(线程函数内应用int kthread_should_stop(void)函数,当返回真时应退出函数),kthread_stop会一直等待至线程结束,线程结束前会发送完成结束给kthread_stop,如果直接使用do_exit直接退出线程那么kthread_stop不会收到完成信号将一直等待下去。如果线程已经退出那么kthread_stop会先设置退出标记再唤醒一下thread,唤醒线程后会判断退出标记因此设定的处理函数不会被调用。如果线程已经被唤醒并已经退出那么kthread_stop会一直等待。
三 源码分析 这里使用的内核版本是2.6.21.5
3.1 管理调度其它的内核线程kthread
使用ps命令可以查看有个名叫kthread的进程,它在内核初始化的时候被创建。
3.2 kthread_create创建线程
再看kthread_create前先看下kthread_create_info结构,每个线程创建时使用。
上面看到创建工作是在keventd_create_kthread函数里,那么看下keventd_create_kthread函数
这时kthread_create在等待create->done信号,内核线程keventd在等待线程创建完create->started。上面创建了线程,处理函数为kthread
至此我们看到kthread_create是如何创建线程,和线程是如何工作的了
3.3 kthread_stop线程的停止
先看下停止相关的结构
这个函数在kthread_stop()被调用后返回真,当返回为真时你的处理函数要返回,返回值会通过kthread_stop()返回。所以你的处理函数应该有判断kthread_should_stop然后退出的代码。
注意如果调用了kthread_stop你的处理函数不能调用do_exit(),函数返回你处理函数的返回值,如果创建的线程还没调用过wake_up_process()那么会返回-EINTR .
四 测试代码
通过几个函数可以很容易的创建内核线程,但线程创建出来之后我们更关注的是有多线程带来的并发和竞争问题。并发的管理是操作系统编程的核心问题之一,引起的错误是一些最易出现又最难发现的问题.