10£®µ÷¶ÈÈÎÎñ
¾³£µØ£¬ÎÒÃÇÓбØÐ붨ʱ×ö»òÕß¾³£×öµÄ¡°¼ÒÎñÊ¡±¡£Èç¹ûÕâ¸öÈÎÎñÓÉÒ»¸ö½ø³ÌÍê³É£¬ÎÒÃÇ¿ÉÒÔ°Ñͨ¹ý°ÑËü·ÅÈëcrontabÎļþ¶ø×öµ½¡£Èç¹ûÕâ¸öÈÎÎñÓÉÒ»¸öÄÚºËÄ£¿éÍê³É£¬ÎÒÃÇÓÐÁ½ÖÖ¿ÉÄܵÄÑ¡Ôñ¡£µÚÒ»ÖÖÊÇ°ÑÒ»¸ö½ø³Ì·ÅÈëcrontabÎļþ£¬Ëü½«ÔÚ±ØÒªµÄʱºòͨ¹ýÒ»¸öϵͳµ÷Óû½ÐÑÄ£¿é£¬±ÈÈç´ò¿ªÒ»¸öÎļþ¡£È»¶ø£¬ÕâÑù×öʱ·Ç³£µÍЧµÄ£¬ÎÒÃÇÐèÒªÔËÐÐÒ»¸öcrontabÍâµÄнø³Ì£¬°ÑÒ»¸öеÄÖ´Ðбí¶ÁÈëÄڴ棬¶øËùÓÐÕâЩֻÊÇΪÁË»½ÐÑÒ»¸öÄÚ´æÖеÄÄÚºËÄ£¿é¡£
ÎÒÃDz»ÐèÒªÕâÑù×ö¡£ÎÒÃÇ¿ÉÒÔ´´½¨Ò»¸öº¯Êý£¬ÔÚÿ¸öʱ¼äÖжÏʱ±»µ÷Ó᣷½·¨ÊÇ´´½¨Ò»¸öÈÎÎñ£¬°üº¬ÔÚÒ»¸ö½á¹¹Ìåtq_structÀÔڴ˽ṹÖаüº¬Ò»¸öÖ¸Ïòº¯ÊýÈë¿ÚµØÖ·µÄÖ¸Õ롣Ȼºó£¬ÎÒÃÇʹÓÃqueue_task°ÑÕâ¸öÈÎÎñ·ÅÈëÒ»¸ö½Ð×ötq_timerµÄÈÎÎñÁбíÖУ¬ÕâÊÇÒ»¸öÔÚÏ´Îʱ¼äÖжÏʱҪִÐеÄÈÎÎñÁÐ±í¡£ÒòΪÎÒÃÇÏ£ÍûÕâ¸öº¯Êý±»³ÖÐøÖ´ÐУ¬ÎÒÃÇÐèÒªÔÚÿ´Îµ÷Óúñ°ÑËü·Å»Øtq_timerÖÐÒÔ±¸Ï´Îʱ¼äÖжϡ£
ÕâÀﻹÓÐÒ»µãÐèÒª¼Çס¡£µ±Ò»¸öÄ£¿é±»rmmodɾ³ýʱ£¬Ê×ÏÈËûµÄË÷Òý¼ÆÊýÆ÷±»¼ì²é¡£Èç¹ûÊÇ0£¬¾Íµ÷ÓÃmodule_cleanup¡£È»ºó£¬Õâ¸öÄ£¿éÒÔ¼°ËüµÄËùÓк¯Êý¶¼´ÓÄÚ´æÖÐɾ³ý¡£Ã»ÓÐÈ˼ì²éÊÇ·ñʱÖÓµÄÈÎÎñÁбíÈÔÈ»°üº¬Ö¸ÏòÕâЩº¯ÊýµÄÖ¸Õ룬¶øÏÖÔÚÒѲ»¿ÉÓ᣺ܾÃÒԺ󣨴ӼÆËã»ú¿´À´£¬ÔÚÈ˵ÄÑÛ¾¦ÀïÊǺ̵ܶģ¬¿ÉÄÜÊÇ°Ù·ÖÖ®Ò»Ã룩£¬ÄÚºËÓÐÁËÒ»¸öʱÖÓÖжϣ¬ÊÔͼµ÷ÓÃÈÎÎñÁбíÖеÄËùÓк¯Êý¡£²»ÐÒµÄÊÇ£¬Õâ¸öº¯ÊýÒѲ»´æÔÚ¡£ÔÚ¶àÊýÇé¿öÏ£¬ËüËùÔÚµÄÄڴ滹δ±»Ê¹Ó㬶øÄãµÃµ½ÁËÒ»¸ö¼«¶Ë´íÎóµÄÐÅÏ¢¡£µ«ÊÇ£¬Èç¹ûÓбðµÄ´úÂë³öÔÚÏàͬµÄµØÖ·£¬Çé¿ö»á·Ç³£Ôã¸â¡£²»ÐÒµÄÊÇ£¬ÎÒÃÇûÓÐÒ»¸ö´ÓÈÎÎñÁбíÖÐ×¢ÏúÒ»¸öÈÎÎñµÄ·½·¨¡£
¼ÈÈ»cleanup_moduleº¯Êý²»ÄÜ·µ»ØÒ»¸ö´íÎóÂí£¨ËüÊÇvoidÐͺ¯Êý£©£¬ÄÇô½â¾ö·½·¨ÊǾͲ»ÒªÈÃËü·µ»Ø¡£¶øÊǵ÷ÓÃsleep_on»òmodule_sleep_on£¨×¢10.1£©°Ñrmmod½ø³Ì¹ÒÆð¡£ÔÚ´Ë֮ǰ£¬ËüÉèÖÃÒ»¸ö±äÁ¿Í¨ÖªÔÚʱÖÓÖжÏʱµ÷Óõĺ¯ÊýÍ£Ö¹¸½¼Ó×Ô¼º¡£ÄÇô£¬ÔÚÏ´ÎʱÖÓÖжÏʱ£¬rmmod½ø³Ì½«±»»½ÐÑ£¬¶øÎÒÃǵĺ¯ÊýÒѾ²»ÔÚ¶ÓÁÐÖУ¬ÕâÑù¾Í¿ÉÒԺܰ²È«µÄɾ³ýÄ£¿é¡£
ex sched.c
/* sched.c - scheduale a function to be called on
* every timer interrupt. */
/* Copyright (C) 1998 by Ori Pomerantz */
/* The necessary header files */
/* Standard in kernel modules */
#include /* Were doing kernel work */
#include /* Specifically, a module */
/* Deal with CONFIG_MODVERSIONS */
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include
#endif
/* Necessary because we use the proc fs */
#include
/* We scheduale tasks here */
#include
/* We also need the ability to put ourselves to sleep
* and wake up later */
#include
/* In 2.2.3 /usr/include/linux/version.h includes a
* macro for this, but 2.0.35 doesnt - so I add it
* here if necessary. */
#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))
#endif
/* The number of times the timer interrupt has been
* called so far */
static int TimerIntrpt = 0;
/* This is used by cleanup, to prevent the module from
* being unloaded while intrpt_routine is still in
* the task queue */
static struct wait_queue *WaitQ = NULL;
static void intrpt_routine(void *);
/* The task queue structure for this task, from tqueue.h */
static struct tq_struct Task = {
NULL, /* Next item in list - queue_task will do
* this for us */
0, /* A flag meaning we havent been inserted
* into a task queue yet */
intrpt_routine, /* The function to run */
NULL /* The void* parameter for that function */
};
/* This function will be called on every timer
* interrupt. Notice the void* pointer - task functions
* can be used for more than one purpose, each time
* getting a different parameter. */
static void intrpt_routine(void *irrelevant)
{
/* Increment the counter */
TimerIntrpt++;
/* If cleanup wants us to die */
if (WaitQ != NULL)
wake_up(&WaitQ); /* Now cleanup_module can return */
else
/* Put ourselves back in the task queue */
queue_task(&Task, &tq_timer);
}
/* Put data into the proc fs file. */
int procfile_read(char *buffer,
char **buffer_location, off_t offset,
int buffer_length, int zero)
{
int len; /* The number of bytes actually used */
/* This is static so it will still be in memory
* when we leave this function */
static char my_buffer[80];
static int count = 1;
/* We give all of our information in one go, so if
* the anybody asks us if we have more information
* the answer should always be no.
*/
if (offset > 0)
return 0;
/* Fill the buffer and get its length */
len = sprintf(my_buffer,
""Timer was called %d times so far "",
TimerIntrpt);
count++;
/* Tell the function which called us where the
* buffer is */
*buffer_location = my_buffer;
/* Return the length */
return len;
}
struct proc_dir_entry Our_Proc_File =
{
0, /* Inode number - ignore, it will be filled by
* proc_register_dynamic */
5, /* Length of the file name */
""sched"", /* The file name */
S_IFREG | S_IRUGO,
/* File mode - this is a regular file which can
* be read by its owner, its group, and everybody
* else */
1, /* Number of links (directories where
* the file is referenced) */
0, 0, /* The uid and gid for the file - we give
* it to root */
80, /* The size of the file reported by ls. */
NULL, /* functions which can be done on the
* inode (linking, removing, etc.) - we dont
* support any. */
procfile_read,
/* The read function for this file, the function called
* when somebody tries to read something from it. */
NULL
/* We could have here a function to fill the
* files inode, to enable us to play with
* permissions, ownership, etc. */
};
/* Initialize the module - register the proc file */
int init_module()
{
/* Put the task in the tq_timer task queue, so it
* will be executed at next timer interrupt */
queue_task(&Task, &tq_timer);
/* Success if proc_register_dynamic is a success,
* failure otherwise */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)
return proc_register(&proc_root, &Our_Proc_File);
#else
return proc_register_dynamic(&proc_root, &Our_Proc_File);
#endif
}
/* Cleanup */
void cleanup_module()
{
/* Unregister our /proc file */
proc_unregister(&proc_root, Our_Proc_File.low_ino);
/* Sleep until intrpt_routine is called one last
* time. This is necessary, because otherwise well
* deallocate the memory holding intrpt_routine and
* Task while tq_timer still references them.
* Notice that here we dont allow signals to
* interrupt us.
*
* Since WaitQ is now not NULL, this automatically
* tells the interrupt routine its time to die. */
sleep_on(&WaitQ);
}
silentwind ÓÚ 2012-03-27 16:41:26·¢±í:
ÔΠдµÄɶÂï...
dzctuser ÓÚ 2012-02-14 13:27:15·¢±í:
ÎÒÒª»ý·Ö¡£¡£¡£
lcdstrongman_hw ÓÚ 2012-01-30 23:03:42·¢±í:
ѧϰ
SongXu ÓÚ 2011-12-23 22:31:39·¢±í:
ѧϰ0:w(5(
ai0909 ÓÚ 2011-10-21 16:12:24·¢±í:
·¹ý¡£¡£¡£