linux 内核 进程api,Linux 内核线程API指南

1. Linux 内核线程简介

Linux 内核线程(KERNEL THREAD)完全独立运行在内核空间,并且不能被切换到用户空间运行,也没有独立内核地址空间。除此之外,与普通的线程一样,可以被调度和抢占。

2. Linux 内核线程相关的API

2.1 内核线程相关头文件

#include

#include

#include

2.2 创建内核线程函数

1). kthread_create 函数用于创建一个内核线程,当时该内核线程并不会马上启动,需要调用wake_up_process启动线程。相关函数详情如下所示。

1 #define kthread_create(threadfn, data, namefmt, arg...) \

2 kthread_create_on_node(threadfn, data, -1, namefmt, ##arg)

1 /**2 * kthread_create_on_node - create a kthread.3 * @threadfn: the function to run until signal_pending(current).4 * @data: data ptr for @threadfn.5 * @node: memory node number.6 * @namefmt: printf-style name for the thread.7 *8 * Description: This helper function creates and names a kernel9 * thread. The thread will be stopped: use wake_up_process() to start10 * it. See also kthread_run().11 *12 * If thread is going to be bound on a particular cpu, give its node13 * in @node, to get NUMA affinity for kthread stack, or else give -1.14 * When woken, the thread will run @threadfn() with @data as its15 * argument. @threadfn() can either call do_exit() directly if it is a16 * standalone thread for which no one will call kthread_stop(), or17 * return when 'kthread_should_stop()' is true (which means18 * kthread_stop() has been called). The return value should be zero19 * or a negative error number; it will be passed to kthread_stop().20 *21 * Returns a task_struct or ERR_PTR(-ENOMEM).22 */

23 struct task_struct *kthread_create_on_node(int (*threadfn)(void *data),24 void *data,25 intnode,26 const charnamefmt[],27 ...)

2). kthread_run 创建内核函数并启动,函数原型如下所示。

1 /**2 * kthread_run - create and wake a thread.3 * @threadfn: the function to run until signal_pending(current).4 * @data: data ptr for @threadfn.5 * @namefmt: printf-style name for the thread.6 *7 * Description: Convenient wrapper for kthread_create() followed by8 * wake_up_process(). Returns the kthread or ERR_PTR(-ENOMEM).9 */

10 #define kthread_run(threadfn, data, namefmt, ...) \

11 ({ \12 struct task_struct *__k \13 =kthread_create(threadfn, data, namefmt, ## __VA_ARGS__); \14 if (!IS_ERR(__k)) \15 wake_up_process(__k); \16 __k; \17 })

3). kthread_stop 函数功能是结束某个线程(do_exit函数也可以实现相同功能),

/**

* kthread_stop - stop a thread created by kthread_create().

* @k: thread created by kthread_create().

*

* Sets kthread_should_stop() for @k to return true, wakes it, and

* waits for it to exit. This can also be called after kthread_create()

* instead of calling wake_up_process(): the thread will exit without

* calling threadfn().

*

* If threadfn() may call do_exit() itself, the caller must ensure

* task_struct can't go away.

*

* Returns the result of threadfn(), or %-EINTR if wake_up_process()

* was never called.*/

int kthread_stop(struct task_struct *k)

4).   schedule_timeout 函数对当前进程进行调度,让其进入睡眠状态,让出占有的系统资源,回到超时唤醒。

/**

* schedule_timeout - sleep until timeout

* @timeout: timeout value in jiffies

*

* Make the current task sleep until @timeout jiffies have

* elapsed. The routine will return immediately unless

* the current task state has been set (see set_current_state()).

*

* You can set the task state as follows -

*

* %TASK_UNINTERRUPTIBLE - at least @timeout jiffies are guaranteed to

* pass before the routine returns. The routine will return 0

*

* %TASK_INTERRUPTIBLE - the routine may return early if a signal is

* delivered to the current task. In this case the remaining time

* in jiffies will be returned, or 0 if the timer expired in time

*

* The current task state is guaranteed to be TASK_RUNNING when this

* routine returns.

*

* Specifying a @timeout value of %MAX_SCHEDULE_TIMEOUT will schedule

* the CPU away without a bound on the timeout. In this case the return

* value will be %MAX_SCHEDULE_TIMEOUT.

*

* In all cases the return value is guaranteed to be non-negative.*/signedlong __sched schedule_timeout(signed long timeout)

3. 使用举例

例程实现在内核中创建两个线程,可以运行成功,当是该例程占用CPU过程,且两个线程之间运行毫无顺序,全靠内核进行调度。综上,如果想要两个线程之间有什么联系,则需要使用linux 内核中的同步与互斥的手段。

#include #include#include#include#include#include

structmytask_struct {

unsignedlong long intcounter;struct task_struct *mykthread1;struct task_struct *mykthread2;

};static struct mytask_struct mytask ={

.counter= 0,

.mykthread1=NULL,

.mykthread2=NULL,

};static int my_thread1(void *data)

{while(1)

{

printk(KERN_INFO"my_thread1 counter %lld\n", ++mytask.counter);

mdelay(1000);

}return 0;

}static int my_thread2(void *data)

{while(1)

{

printk(KERN_INFO"my_thread2 counter %lld\n", ++mytask.counter);

mdelay(1000);

}return 0;

}static int __init thread_init(void)

{

mytask.mykthread1= kthread_create(my_thread1,NULL,"my_thread1");if(IS_ERR(mytask.mykthread1))

{

printk(KERN_EMERG"Create thread1 fail\n");returnPTR_ERR(mytask.mykthread1);

}

mytask.mykthread2= kthread_run(my_thread2,NULL,"my_thread2");if(IS_ERR(mytask.mykthread2))

{

printk(KERN_EMERG"Create thread2 fail\n");

kthread_stop(mytask.mykthread1);returnPTR_ERR(mytask.mykthread2);

}return 0;

}static void __exit thread_exit(void)

{

kthread_stop(mytask.mykthread1);

kthread_stop(mytask.mykthread2);return;

}

module_init(thread_init);

module_exit(thread_exit);

MODULE_AUTHOR("https://www.cnblogs.com/Lyunfei/tag/");

MODULE_DESCRIPTION("Linux Kthread");

MODULE_LICENSE("GPL");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值