功能:實作一個多線程同時删除,增加的連結清單
要點:同時使用鎖,消息隊列,定時器,原子操作
#include<linux/init.h>
#include<linux/module.h>
#include<linux/list.h>
#include<linux/semaphore.h>
#include<linux/sched.h>
#include<linux/timer.h>
#include<linux/spinlock_types.h>
#include<linux/workqueue.h>
#include<linux/slab.h>
#include<linux/kthread.h>
#include<linux/kallsyms.h>
#include<linux/atomic.h>
typedef struct mystruct{
struct list_head list;
int id;
int pid;
}my_str,*my_pstr;
static LIST_HEAD(head);
static DEFINE_SPINLOCK(my_lock);
static struct work_struct queue;
static DEFINE_SEMAPHORE(sem);
static struct timer_list mytimer;
static unsigned int list_len = 0;
static atomic_t my_count = ATOMIC_INIT(0);
static int count = 0;
static int sharelist(void *data)
{
my_pstr m_list;
if(count++ % 4 == 0)
printk("\n");
spin_lock(&my_lock);
if(list_len < 50){
if((m_list = kmalloc(sizeof(my_str),GFP_KERNEL)) == NULL )
return -ENOMEM;
m_list->id = atomic_read(&my_count);
atomic_inc(&my_count);
m_list->pid = current->pid;
list_add(&m_list->list, &head);
list_len++;
printk("thread add :%5d\n",m_list->id);
}else{
m_list = list_entry(head.prev,my_str,list);
list_del(&m_list->list);
list_len--;
printk("Thread del %5d\n",m_list->id);
kfree(m_list);
}
spin_unlock(&my_lock);
return 0;
}
static void start_kthread(void)
{
down(&sem);
schedule_work(&queue);
}
static void kthread_launcher(struct work_struct *q)
{
kthread_run(sharelist,NULL,"%d",count);
up(&sem);
}
void qt_task(unsigned long data)
{
spin_lock(&my_lock);
if(!list_empty(&head)){
my_pstr my_list;
if(count++ % 4 == 0)
printk("\n");
my_list = list_entry(head.next, my_str, list);
list_del(&my_list->list);
list_len--;
printk("timer del : %5d\n",my_list->id);
kfree(my_list);
}
spin_unlock(&my_lock);
mod_timer(&mytimer,jiffies + msecs_to_jiffies(1000));
}
static int __init share_init(void)
{
int i;
printk("shar init\n");
INIT_WORK(&queue,kthread_launcher);
setup_timer(&mytimer,qt_task,0);
add_timer(&mytimer);
for(i = 0; i < 200; i++)
start_kthread();
return 0;
}
static void __exit share_exit(void)
{
struct list_head *n= NULL;
struct list_head *p =NULL;
my_pstr my;
printk("\n share list exit\n");
del_timer(&mytimer);
spin_lock(&my_lock);
list_for_each_safe(p,n,&head){
if(count++ % 4 == 0)
printk("\n");
my = list_entry(p,my_str,list);
list_del(p);
printk("exit:del %d\n",my->id);
kfree(my);
}
spin_unlock(&my_lock);
printk("all exit");
}
module_init(share_init);
module_exit(share_exit);
MODULE_LICENSE("GPL");