linux内核线程和普通线程的区别,linux内核线程绑定cpu
创建内核线程:
struct task _ struct * kthread _ create(int(* thread fn)(void * data),
void *data,const char name fmt[]);
唤醒内核线程(可以唤醒所有进程(线程)):
wake _ up _ process(struct task _ struct * k);
创建并运行内核线程:
struct task _ struct * kthread _ run(int(* thread fn)(void * data),
void *data,const char name fmt[]);
通知内核线程停止:
int kthread _ stop(struct task _ struct * k);
返回螺纹【数学】函数函数的返回值,如果k没有被唤醒进程(k)过将返回-EINTR
不是强制停止,如果内核线程不停止将一直等待
检查是否收到停止信号:
int kthread _ should _ stop(void);
kthread_create与内核线程的区别
从表面上来看,这两个函数非常的类似,但是实现却是相差甚远。
kthread_create是通过工作队列来实现的,内核线程是通过做_叉来实现的。
内核线程可以用内核线程创建,但是在执行函数里面必须用后台运行释放资源并挂到初始化下,还需要用完成等待这一过程的完成。
kthread_create是比较正牌的创建函数,这个不必要调用妖魔化,用这个创建的内核线程都挂在了内核线程线程下。
可以在非内核线程中调用内核线程,但这样创建的线程必须在自己调用妖魔化(.)来释放资源,成为真正的内核线程。
#包含linux/kernel.h
#包含linux/module.h
静态int noop(void *dummy)
{
int I=0;
daemonize( mythread );
while(i 5) {
printk(current- mm=%pn ,当前-
printk(current- active_mm=%pn ,current-active _ mm);
设置当前状态(任务可中断);
schedule _ time out(10 * HZ);
}
返回0;
}
静态int test_init(空)
{
kernel_thread(noop,NULL,CLONE _ KERNEL SIGCHLD);
返回0;
}
静态void test_exit(void) {}
模块初始化(测试_初始化);
模块_出口(测试_退出);
《流言蜚语》就是给这个内核线程取的名字,可以用ps -A来查看。
计划()用于进程调度,可以理解为放弃中央处理器的使用权。
kthread_create创建线程
一使用kthread_create创建线程:
struct task _ struct * kthread _ create(int(* thread fn)(void * data),
无效*数据,
const char *namefmt,);
这个函数可以像最高一样传入某种格式的线程名
线程创建后,不会马上运行,而是需要将kthread_create()返回的任务结构指针传给唤醒进程(),然后通过此函数运行线程。
2.当然,还有一个创建并启动线程的函数:kthread_run
struct task _ struct * kthread _ run(int(* thread fn)(void * data),
无效*数据,
const char *namefmt,);
3.线程一旦启动起来后,会一直运行,除非该线程主动调用do_exit函数,或者其他的进程调用k线程_停止函数,结束线程的运行。
int kthread _ stop(struct task _ struct * thread);
kthread_stop()通过发送信号给线程。
如果线程函数正在处理一个非常重要的任务,它不会被中断的。当然如果线程函数永远不返回并且不检查信号,它将永远都不会停止。
参考:内核线程变得简单
查看剪贴板打印文本?
#包含linux/kthread.h
静态结构任务结构* _任务
静态结构任务结构* _任务2
静态结构任务结构* _任务3
静态int thread_func(void *data)
{
int j,k;
(同Internationalorganizations)国际组织超时;
等待队列头超时队列
静态int I=0;
我;
j=0;
k=I;
printk(thread_func %d startedn ,I);
init _ wait queue _ head(time out _ wq);
而(!kthread_should_stop())
{
interruptible _ sleep _ on _ time out(超时_ wq,HZ);
正在睡眠.%dn ,k,j);
}
返回0;
}
空的我的开始线程(无效)
{
//_ task=kthread _ create(thread _ func,NULL, thread _ func 2 );
//wake _ up _ process(_ task);
_task=kthread_run(thread_func,NULL, thread _ func 2 );
_task2=kthread_run(thread_func,NULL, thread _ func 2 );
_task3=kthread_run(thread_func,NULL, thread _ func 2 );
如果(!IS_ERR(_task))
{
printk( kthread _ create done n );
}
其他
{
printk( kthread _ create error n );
}
}
空的我的结束线程(无效)
{
int ret=0;
ret=kthread _ stop(_ task);
printk(结束线程ret=%dn ,ret);
ret=kthread _ stop(_ task 2);
printk(结束线程ret=%dn ,ret);
ret=kthread _ stop(_ task 3);
printk(结束线程ret=%dn ,ret);
}
#包含linux/kthread.h
静态结构任务结构* _任务
静态结构任务结构* _任务2
静态结构任务结构* _任务3
静态int thread_func(void *data)
{
int j,k;
(同Internationalorganizations)国际组织超时;
等待队列头超时队列
静态int I=0;
我;
j=0;
k=I;
printk(thread_func %d startedn ,I);
init _ wait queue _ head(time out _ wq);
而(!kthread_should_stop())
{
interruptible _ sleep _ on _ time out(超时_ wq,HZ);
正在睡眠.%dn ,k,j);
}
返回0;
}
空的我的开始线程(无效)
{
//_ task=kthread _ create(thread _ func,NULL, thread _ func 2 );
//wake _ up _ process(_ task);
_task=kthread_run(thread_func,NULL, thread _ func 2 );
_task2=kthread_run(thread_func,NULL, thread _ func 2 );
_task3=kthread_run(thread_func,NULL, thread _ func 2 );
如果(!IS_ERR(_task))
{
printk( kthread _ create done n );
}
其他
{
printk( kthread _ create error n );
}
}
空的我的结束线程(无效)
{
int ret=0;
ret=kthread _ stop(_ task);
printk(结束线程ret=%dn ,ret);
ret=kthread _ stop(_ task 2);
printk(结束线程ret=%dn ,ret);
ret=kthread _ stop(_ task 3);
printk(结束线程ret=%dn ,ret);
}
在执行k线程_停止的时候,目标线程必须没有退出,否则会哎呀。原因很容易理解,当目标线程退出的时候,其对应的工作结构也变得无效,k线程_停止引用该无效工作结构就会出错。
这种退出机制很温和,一切尽在线程函数()的掌控之中,线程在退出时可以从容地释放资源,而不是莫名其妙地被人"暗杀"。