今天用linux的list.h头文件实现了约瑟夫环。
笔者这里使用的办法比较老土。
基本思想:
第一、本来是要用链表来实现的,但是内核态下,内存的分配;不是很了解。故这里使用了数组元素作为每一个链表的节点。也就是说,这个节点的个数是事先知道的。然后将其链接成一个双向循环链表。
第二、约瑟夫环的实现原理,就是将n个人站成一个环,并假定从某个人开始编号为1,以后一次编号加一。编号结束之后,选择一个数字m作为跳出的条件,从第一个人开始数,当数到m的人边退出这个环,然后接着从下一个人重新开始数数,直到只剩一个人为止!
源代码如下:
- 1 #include <linux/module.h>
-
2 #include <linux/init.h>
-
3 #include <linux/kernel.h>
-
4 #include <linux/list.h>
-
5
-
6 struct Data{
-
7 int data;
-
8 struct list_head list;
-
9 };
-
10 static int __init start_init(void);
-
11 static void __exit end_exit(void);
-
12
-
13 static int __init start_init()
-
14 {
-
15 struct list_head *q;
-
16 struct Data *p;
-
17 struct Data data[7];
-
18 int i,count;
-
19
-
20 LIST_HEAD(head);
-
21
-
22 printk("Start Joesphus...\n");
-
23 for(i = 0 ; i < 7 ; i++){
-
24 p = &data[i];
-
25 p->data = i+1;
-
26 list_add_tail(&p->list,&head);
-
27 }
-
28
-
29 q = (&head)->next;
-
30 list_del(&head);
-
31 count = 1;
-
32 while(!list_empty(q)){
-
33 for(i = 0 ; i < 2 ; i++)
-
34 q = q->next;
-
35 p = container_of(q,struct Data,list);
-
36 printk("%d-----%d\n",count,p->data);
-
37 count++;
-
38 q = q->next;
-
39 list_del(&p->list);
-
40 }
-
41 p = container_of(q,struct Data,list);
-
42 printk("%d-----%d\n",count,p->data);
-
-
43 list_del(&p->list);
-
44 printk("End Josephus...\n");
-
45
-
46 return 0;
-
47 }
-
48 static void __exit end_exit()
-
49 {
-
50 printk("Exit of this program...\n");
-
51 }
-
52 module_init(start_init);
-
53 module_exit(end_exit);
Makefile文件如下:
- 1 ifneq ($(KERNELRELEASE),)
-
2 mymodule-objs:= yuesefu.c
-
3 obj-m += yuesefu.o
-
4
-
5 else
-
6 PWD :=$(shell pwd)
-
7 KVER := $(shell uname -r)
-
8 KDIR :=/lib/modules/$(KVER)/build
-
9
-
10 all:
-
11 $(MAKE) -C $(KDIR) M=$(PWD)
-
12 clean:
-
13 rm -rf *.o *.mod.c *.ko *.symvers *order *.markers *-
-
14 endif
关于该Makefile文件的解释,请见笔者的上一篇博文。
执行命令:
- [#44#caopeng@laptop:~/kernel]$make
-
make -C /lib/modules/2.6.32-33-generic/build M=/home/caopeng/kernel
-
make[1]: 正在进入目录 `/usr/src/linux-headers-2.6.32-33-generic'
-
LD /home/caopeng/kernel/built-in.o
-
CC [M] /home/caopeng/kernel/yuesefu.o
-
Building modules, stage 2.
-
MODPOST 1 modules
-
CC /home/caopeng/kernel/yuesefu.mod.o
-
LD [M] /home/caopeng/kernel/yuesefu.ko
-
make[1]:正在离开目录 `/usr/src/linux-headers-2.6.32-33-generic'
-
[#45#caopeng@laptop:~/kernel]$sudo insmod yuesefu.ko
-
[sudo] password for caopeng:
-
[#46#caopeng@laptop:~/kernel]$sudo rmmod yuesefu.ko
-
[#47#caopeng@laptop:~/kernel]$
执行结果可以在/var/log/messages查看到如下结果。
[#12#caopeng@laptop:~/kernel]$tail /var/log/messages
Sep 18 23:39:48 laptop kernel: [ 8676.733067] Start Joesphus...
Sep 18 23:39:48 laptop kernel: [ 8676.733069] 1-----3
Sep 18 23:39:48 laptop kernel: [ 8676.733071] 2-----6
Sep 18 23:39:48 laptop kernel: [ 8676.733072] 3-----2
Sep 18 23:39:48 laptop kernel: [ 8676.733073] 4-----7
Sep 18 23:39:48 laptop kernel: [ 8676.733075] 5-----5
Sep 18 23:39:48 laptop kernel: [ 8676.733076] 6-----1
Sep 18 23:39:48 laptop kernel: [ 8676.733077] 7-----4
Sep 18 23:39:48 laptop kernel: [ 8676.733078] End Josephus...
Sep 18 23:40:03 laptop kernel: [ 8691.687480] Exit of this program...
[#13#caopeng@laptop:~/kernel]$
有关list.h的相关知识,请查阅笔者前几篇博文!!
阅读(5618) | 评论(3) | 转发(1) |