Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1357360
  • 博文数量: 281
  • 博客积分: 8800
  • 博客等级: 中将
  • 技术积分: 3346
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-17 22:31
文章分类

全部博文(281)

文章存档

2013年(1)

2012年(18)

2011年(16)

2010年(44)

2009年(86)

2008年(41)

2007年(10)

2006年(65)

我的朋友

分类: LINUX

2008-12-01 15:18:28

#include

#include



static pid_t thread_pid;

static struct completion thread_exited;

static int noop(void *dummy)

{

daemonize("mythread");

allow_signal(SIGTERM);

while (!signal_pending (current)) {

                /* do something else */

schedule();

}

complete_and_exit(&thread_exited, 1);

}



static int test_init(void)

{

init_completion(&thread_exited);

thread_pid = kernel_thread(noop, NULL, CLONE_KERNEL | SIGCHLD);

return 0;

}



static void test_exit(void)

{

kill_proc (thread_pid, SIGTERM, 1);

wait_for_completion(&thread_exited);

}

module_init(test_init);

module_exit(test_exit);
 
 
”mythread“就是给这个内核线程取的名字, 可以用ps -A来查看。
schedule()用于进程调度, 可以理解为放弃CPU的使用权.
 
static int reporter_thread(void *__unused)
{
/*
* This thread doesn't need any user-level access,
* so get rid of all our resources
*/

daemonize("reported_thread");
allow_signal(SIGKILL);
do {
.......

} while(1);
complete_and_exit(&reporter_exited,0);
}
static void page_fault_seeker_exit(void)
{
....
kill_proc(pid, SIGKILL, 1);

/*kernel thread must be killed before module unloaded
*wait for the completion of kernel thread
*/
wait_for_completion(&reporter_exited);
...

}
 
可以在非内核线程中调用kernel_thread, 但这样创建的线程必须在自己调用daemonize(...)来释放资源, 成为真正的内核线程。

#include
#include

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);
 

这还有一个在其它内核线程中调用kernel_thread的例子。 这个的current->mm就为零了。

static struct work_struct work;
static int noop(void *dummy)
{
printk("current->mm = %p\n", current->mm);
return 0;
}
static void create_thread(void *dummy)
{
kernel_thread(noop, NULL, CLONE_KERNEL | SIGCHLD);
}
static int test_init(void)
{
INIT_WORK(&work, create_thread, NULL);
schedule_work(&work);
}
static void test_exit(void) {}
module_init(test_init);
module_exit(test_exit);

大部分情况, 都可以创建一个 work_queue来代替。

 

 

/*
 * Let kernel threads use this to say that they
 * allow a certain signal (since daemonize() will
 * have disabled all of them by default).
 */
int allow_signal(int sig)



内核线程函数里先调用daemonize去掉mm,fs 等资源后   禁止所有信号

如果需要,调用allow_signal  允许某个信号

 

 

kernel daemons & blocking mutex

March 12, 2007 - 4:27am
Submitted by on March 12, 2007 - 4:27am.
Linux

/********************************************************************
*Description :: A kernel module which creates 2 kernel threads.
* Converts both of them to daemons.Demonstrates the use of mutex
* to share a dummy resource between the two.
* The mutex is acquired using a blocking call :down_interruptible()
*Author :: Milind A Choudhary
*Date ::07-Dec-2005
********************************************************************/

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

/* The resource which will be shared */
struct data {
int num;
}data={11};

pid_t kthread_pid1 ;
pid_t kthread_pid2 ;
DECLARE_MUTEX(mutex);

/*Routine for the first thread */

int kthread_routine_1(void *kthread_num)
{
//int num=(int)(*(int*)kthread_num);
int num=1;
char kthread_name[15];

printk(KERN_INFO "Inside daemon_routine() \n");
sprintf(kthread_name,"kern_daemon_%d",num);
daemonize(kthread_name);
allow_signal(SIGKILL);
allow_signal(SIGTERM);

do{
printk(KERN_INFO "kernel_daemon [%d] waiting to acquire mutex\n",num);
if(!down_interruptible(&mutex)){
printk(KERN_INFO "kernel_daemon [%d] accessing the shared data=%d\n",num,data.num);
data.num=11;
up(&mutex);
printk(KERN_INFO "kernel_daemon [%d] released the mutex data=%d\n",num,data.num);
}else{
printk(KERN_INFO "kernel_daemon [%d] interrupted while acquiring the mutex\n",num);
}

set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(5*HZ);

}while(!signal_pending(current));
return 0;
}

/*Routine for the second thread */

int kthread_routine_2(void *kthread_num)
{
//int num=(int)(*(int*)kthread_num);
int num=2;
char kthread_name[15];

printk(KERN_INFO "Inside daemon_routine() \n");
sprintf(kthread_name,"kern_daemon_%d",num);
daemonize(kthread_name);
allow_signal(SIGKILL);
allow_signal(SIGTERM);

do{
printk(KERN_INFO "kernel_daemon [%d] waiting to acquire mutex\n",num);
if(!down_interruptible(&mutex)){
printk(KERN_INFO "kernel_daemon [%d] accessing the shared data=%d\n",num,data.num);
data.num=22;
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(10*HZ);
up(&mutex);
printk(KERN_INFO "kernel_daemon [%d] released the mutex data=%d\n",num,data.num);
}else{
printk(KERN_INFO "kernel_daemon [%d] interrupted while acquiring the mutex\n",num);
}

set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(10*HZ);

}while(!signal_pending(current));
return 0;
}

int _init_(void)
{
int kthread_num =1;
printk(KERN_INFO"starting the first kernel thread\n");
kthread_pid1 = kernel_thread(kthread_routine_1,NULL,0);
if(kthread_pid1< 0 ){
printk(KERN_ALERT "Kernel thread [1] creation failed\n");
return -1;
}
kthread_num=2;
printk(KERN_INFO"starting the second kernel thread\n");
kthread_pid2 = kernel_thread(kthread_routine_2,NULL,0);
if(kthread_pid2 < 0 ){
printk(KERN_ALERT "Kernel thread [2] creation failed\n");
return -1;
}

return 0;
}

void _fini_(void)
{
printk(KERN_INFO"kernel daemon [1] terminating\n");
if(kill_proc(kthread_pid1,SIGTERM,1) == -ESRCH){
printk(KERN_ERR "kernel thread1 pid::%d already dead\n",kthread_pid1);
init_MUTEX(&mutex);
}
printk(KERN_INFO"kernel daemon [2] terminating\n");
if(kill_proc(kthread_pid2,SIGTERM,1) == -ESRCH){
printk(KERN_ERR "kernel thread2 pid::%d already dead\n",kthread_pid2);
init_MUTEX(&mutex);
}
}

module_init(_init_);
module_exit(_fini_);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Demonstrates use of mutex");
MODULE_AUTHOR("Milind A Choudhary");

 

 

/*
* file mythread.c
*/
#include
#include
#include
#include
#include

#include
#include
#include

/*
        struct student {
                int age;
                char name[128];
                int score;
        };
*/

static pid_t thread_id;
struct completion exit_completion;

int my_fuction(void *arg)
{
        daemonize("demo-thread");
        allow_signal(SIGKILL);

        while(!signal_pending(current))
        {
                printk("jiffies is %lu\n", jiffies);

                set_current_state(TASK_INTERRUPTIBLE);
                schedule_timeout(10 * HZ);
        }


        complete_and_exit(&exit_completion, 1);
        return 0;
}

static int __init init(void)
{
        thread_id = kernel_thread(my_fuction, NULL, CLONE_FS | CLONE_FILES);
        return 0;
}

static void __exit fini(void)
{
        kill_proc(thread_id, SIGKILL, 1);
        wait_for_completion(&exit_completion);
        printk("Goodbye\n");
}

module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");


 


阅读(3493) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~