信号量使用实例

7 views
Skip to first unread message

牛涛

unread,
Sep 23, 2008, 12:54:56 AM9/23/08
to 操作系统课程论坛
#include<linux/init.h>
#include<linux/module.h>
#include<linux/sched.h>
#include<linux/sem.h>
MODULE_LICENSE("Dual BSD/GPL");
int num[2][5]={
{0,2,4,6,8},
{1,3,5,7,9}
};
struct semaphore sem_first;
struct semaphore sem_second;
int thread_print_first(void *);
int thread_print_second(void *);
int thread_print_first(void *p)
{
int i;
int *num=(int *)p;
for(i=0;i<5;i++) {
down(&sem_first);
printk(KERN_INFO"Hello World:%d\n",num[i]);
up(&sem_second);
}
return 0;
}
int thread_print_second(void *p)
{
int i;
int *num=(int *)p;
for(i=0;i<5;i++) {
down(&sem_second);
printk(KERN_INFO"Hello World:%d\n",num[i]);
up(&sem_first);
}
return 0;
}
static int hello_init(void)
{
printk(KERN_ALERT"Hello World enter\n");
init_MUTEX(&sem_first);
init_MUTEX(&sem_second);
kernel_thread(thread_print_first,num[0],CLONE_KERNEL);
kernel_thread(thread_print_second,num[1],CLONE_KERNEL);
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT"hello world exit\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("Niu Tao");
MODULE_DESCRIPTION("A simple hello world Module");
MODULE_ALIAS("a simplest module");


Makefile:

obj-m :=hello.o
CURRENT_PATH := $(shell pwd)
LINUX_KERNEL := $(shell uname -r)
LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL)

all:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions
Module.symvers .Makefile.swp


功能:使用信号量实现数据的顺序打印
运行结果:
[ 7538.928624] Hello World enter
[ 7538.928846] Hello World:0
[ 7538.940529] Hello World:1
[ 7538.940584] Hello World:2
[ 7538.940840] Hello World:3
[ 7538.940844] Hello World:4
[ 7538.941038] Hello World:5
[ 7538.941042] Hello World:6
[ 7538.941218] Hello World:7
[ 7538.941222] Hello World:8
[ 7538.941408] Hello World:9
[ 7562.273176] hello world exit

牛涛

unread,
Sep 23, 2008, 12:56:18 AM9/23/08
to 操作系统课程论坛
本站网友 时间:2008-09-22 10:51:04
请问为何不是 1,0,3,2...是不是这两句对调一下,就会如我所想的了:
kernel_thread(thread_print_first,num[0],CLONE_KERNEL);
kernel_thread(thread_print_second,num[1],CLONE_KERNEL);
这两个线程一旦创建,这会立刻被运行吗?

niutao.linux 时间:2008-09-22 19:07:23 IP地址:221.11.22.★
把这两句
kernel_thread(thread_print_first,num[0],CLONE_KERNEL);
kernel_thread(thread_print_second,num[1],CLONE_KERNEL);
掉换一下,结果就如你所说。另外kernel_thread()实际上是调用sys_clone(),
而sys_clone()调用的是do_fork(),此处传递的参数是CLONE_KERNEL,所以
创建的线程会被调用wake_up_new_task()函数唤醒执行,详细见do_fork()函数:
if (!(clone_flags & CLONE_STOPPED))
wake_up_new_task(p, clone_flags);
else
p->state = TASK_STOPPED;
是立刻运行。

李则良

unread,
Sep 24, 2008, 8:58:50 AM9/24/08
to xiyouo...@googlegroups.com
2008/9/23 牛涛 <niuta...@gmail.com>:
换位后我的运行情况:
$ dmesg |tail
[ 3528.186725] Hello World:1
[ 3528.186739] Hello World:0
[ 3528.186745] Hello World:3
[ 3528.186750] Hello World:2
[ 3528.186755] Hello World:5
[ 3528.186760] Hello World:4
[ 3528.186765] Hello World:7
[ 3528.186769] Hello World:6
[ 3528.186775] Hello World:9
[ 3528.186784] Hello World:8

BTW:我的平台还是用不了这个Makefile
改为:
obj-m :=sem.o
CURRENT_PATH := $(shell pwd)
LINUX_KERNEL := 2.6.24-15-generic
LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL)

all:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:

make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean


>
> niutao.linux 时间:2008-09-22 19:07:23 IP地址:221.11.22.★
> 把这两句
> kernel_thread(thread_print_first,num[0],CLONE_KERNEL);
> kernel_thread(thread_print_second,num[1],CLONE_KERNEL);
> 掉换一下,结果就如你所说。另外kernel_thread()实际上是调用sys_clone(),

我不没找到相关证据,而是看到 linux/arch/ia64/kernel/process.c :

675pid_t
676kernel_thread (int (*fn)(void *), void *arg, unsigned long flags)
677{
678 extern void start_kernel_thread (void);
679 unsigned long *helper_fptr = (unsigned long *) &start_kernel_thread;
680 struct {
681 struct switch_stack sw;
682 struct pt_regs pt;
683 } regs;
684
685 memset(&regs, 0, sizeof(regs));
686 regs.pt.cr_iip = helper_fptr[0]; /* set entry point (IP) */
687 regs.pt.r1 = helper_fptr[1]; /* set GP */
688 regs.pt.r9 = (unsigned long) fn; /* 1st argument */
689 regs.pt.r11 = (unsigned long) arg; /* 2nd argument */
690 /* Preserve PSR bits, except for bits 32-34 and 37-45,
which we can't read. */
691 regs.pt.cr_ipsr = ia64_getreg(_IA64_REG_PSR) | IA64_PSR_BN;
692 regs.pt.cr_ifs = 1UL << 63; /* mark as valid,
empty frame */
693 regs.sw.ar_fpsr = regs.pt.ar_fpsr = ia64_getreg(_IA64_REG_AR_FPSR);
694 regs.sw.ar_bspstore = (unsigned long) current + IA64_RBS_OFFSET;
695 regs.sw.pr = (1 << PRED_KERNEL_STACK);
696 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
&regs.pt, 0, NULL, NULL);
697}
698EXPORT_SYMBOL(kernel_thread);

还有在linux/arch/frv/kernel/kernel_thread.S下有:
###############################################################################
26#
27# Create a kernel thread
28#
29# int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
30#
31###############################################################################
32 .globl kernel_thread
33 .type kernel_thread,@function
34kernel_thread:
35 or.p gr8,gr0,gr4
36 or gr9,gr0,gr5
37
38 # start by forking the current process, but with shared VM
39 setlos.p #__NR_clone,gr7 ; syscall number
40 ori gr10,#CLONE_VM,gr8 ; first syscall
arg [clone_flags]
41 sethi.p #0xe4e4,gr9 ; second syscall
arg [newsp]
42 setlo #0xe4e4,gr9
43 setlos.p #0,gr10 ; third syscall
arg [parent_tidptr]
44 setlos #0,gr11 ; fourth syscall
arg [child_tidptr]
45 tira gr0,#0
46 setlos.p #4095,gr7
47 andcc gr8,gr8,gr0,icc0
48 addcc.p gr8,gr7,gr0,icc1
49 bnelr icc0,#2
50 bc icc1,#0,kernel_thread_error
51
52 # now invoke the work function
53 or gr5,gr0,gr8
54 calll @(gr4,gr0)
55
56 # and finally exit the thread
57 setlos #__NR_exit,gr7 ; syscall number
58 tira gr0,#0

Niu Tao

unread,
Sep 26, 2008, 8:09:10 AM9/26/08
to xiyouo...@googlegroups.com
2008/9/24 李则良 <lizelia...@gmail.com>:
哦,我参考的这篇文章:http://www.sudu.cn/info/html/edu/linux/20070102/290258.html
于是就直接看sys_clone了。这篇文章比较早,还可能是其他平台的,而在x86等上是直接调用
do_fork()的。大意~

--
My Bolg: http://niutao.cublog.cn

Niu Tao

unread,
Sep 27, 2008, 11:37:39 PM9/27/08
to xiyouo...@googlegroups.com
2008/9/26 Niu Tao <niuta...@gmail.com>:
关于这个程序的讨论在:
http://www.lupaworld.com/bbs/viewthread.php?tid=39389
Reply all
Reply to author
Forward
0 new messages