内核任务及其之间的并发关系

实验代码:
share.c :

#include <linux/module.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/sched.h>
#include <linux/list.h>
#include <linux/semaphore.h>
#include <linux/slab.h>
#include <linux/kthread.h>


#define NTHREADS 200  //线程数

struct my_struct {
	struct list_head list;
	int id;
	int pid;
};
static struct  work_struct queue;
static struct timer_list mytimer;
static LIST_HEAD(mine);
static unsigned int list_len = 0;
static DEFINE_SEMAPHORE(sem);
static DEFINE_SPINLOCK(my_lock);
static atomic_t my_count = ATOMIC_INIT(0);
static long count = 0;
static int timer_over = 0;

static int sharelist(void *data);
static void kthread_launcher(struct work_struct *q);
static void start_kthread(void);
void qt_task(unsigned long data);

static int __init share_init(void)
{
	int i;

	printk(KERN_INFO"share list enter\n");
	INIT_WORK(&queue, kthread_launcher);//初始化工作队列
	setup_timer(&mytimer, qt_task, 0);//设置定时器
	add_timer(&mytimer);//添加定时器
	for (i = 0; i < NTHREADS; i++)//再启动200个内核线程来添加节点
		start_kthread();
	return 0;
}

static int sharelist(void * data)
{
	struct my_struct *p;
	if (count++ % 4 == 0)
		printk("\n"); 
	spin_lock(&my_lock);   /*添加锁,保护共享资源*/
	if (list_len < 100)
	{
		if ((p = kmalloc(sizeof(struct my_struct), GFP_KERNEL)) == NULL)
			return -ENOMEM;
		p->id = atomic_read(&my_count);   /*原子变量操作*/
	    atomic_inc(&my_count);
		p->pid=current->pid;
		list_add(&p->list,&mine);   /*向队列中添加新节点*/
		list_len++;
		printk("THREAD ADD:%-5d\t",p->id);
	}
	else
	{/*队列超过定长则删除节点*/
		struct my_struct *my = NULL;
		my = list_entry(mine.prev, struct my_struct, list);
		list_del(mine.prev);   /*从队列尾部删除节点*/
		list_len--;
		printk("THREAD DEL:%-5d\t", my->id);
		kfree(my);
	}
	spin_unlock(&my_lock);
	return 0;
}

void kthread_launcher(struct work_struct *q)
{
kthread_run(sharelist,NULL,"hello_1");  /*创建内核线程*/
	up(&sem);
}

static void start_kthread(void)
{
	down(&sem);
	schedule_work(&queue);   	/*调度工作队列*/
}

void qt_task(unsigned long data)
{
	if(!list_empty(&mine)){	
	struct my_struct *i;
	if(count++ % 4 == 0)
	     printk("\n");
	i = list_entry(mine.next , struct my_struct ,list); /*取下一个结点*/
	list_del(mine.next);    /*删除结点*/
	list_len --;
	printk("TIMER DEL:% -5d\t", i->id);
	kfree(i);

	}
    mod_timer(&mytimer,jiffies+1);   /*修改定时器时间*/
	
}

static void __exit share_exit(void)
{
	struct  list_head *n , *p = NULL;
	struct my_struct *my = NULL;
	printk("\nshare list exit\n");
	del_timer(&mytimer);
	spin_lock(&my_lock);	 /*上锁,以保护临界区*/
	list_for_each_safe(p,n,&mine){		 /*删除所有节点,销毁链表*/
	     if(count++ %4 == 0)
		printk("\n");
	  my = list_entry(p, struct my_struct,list);   /*取下一个结点*/
	  list_del(p);
	printk("SYSCALL DEL: %d\t",my->id);
	kfree(my);
	
	}

 	spin_unlock(&my_lock);	 /*开锁*/
	printk(KERN_INFO"Over\n");

}

module_init(share_init);
module_exit(share_exit);

MODULE_LICENSE("GPL");  





Makefile :
ifneq ($(KERNELRELEASE),)
	obj-m := share.o
#obj-m 指编译成外部模块
else
	KERNELDIR := /lib/modules/$(shell uname -r)/build

	PWD := $(shell pwd)
modules:
	make -C $(KERNELDIR) M=$(PWD) modules	
endif
clean:
	make -C $(KERNELDIR) M=$(PWD) clean

上面的代码是参考了一些问题解决方案之后成功运行的版本,常见的问题解决方案为:

  1. 在2.6.36版本后的内核就没有DECLARE_MUTEX这个宏了,取而代之的是DEFINE_SEMAPHORE宏
  2. SPIN_LOCK_UNLOCKED已被弃用自2.6.19,在2.6.39中删除。将static spinlock_t my_lock = SPIN_LOCK_UNLOCKED;
    改为static DEFINE_SPINLOCK(my_lock);
  3. kernel_thread没有EXPORT_SYMBOL
    换成kthread_run

感谢阅读~~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值