现在的位置: 首页 > 综合 > 正文

【转】Linux那些事儿之我是U盘(33)彼岸花的传说(一)

2013年05月02日 ⁄ 综合 ⁄ 共 2082字 ⁄ 字号 评论关闭

彼岸花,花语是悲伤的回忆.

很久很久以前,城市的边缘开满了大片大片的曼珠沙华,它的花香有一种魔力,可以让人想起自己前世的事情.守护曼珠沙华的是两个妖精,一个是花妖叫曼珠,一个是叶妖叫沙华.他们守侯了几千年,可是从来没有见过面,因为开花的时候,就没有叶子,有叶子的时候没有花.他们疯狂地想念着彼此,并被这种痛苦折磨着.终于有一天,他们决定违背神的规定偷偷地见一次面.那一年的曼珠沙华红艳艳的花被惹眼的绿色衬托着,开得格外妖冶美丽.

曼珠和沙华受到惩罚,被打入轮回,并被诅咒永远也不能在一起,生生世世在人世间受到磨难.从那以后,蔓珠沙华又叫彼岸花,意思是开放在天国的花,它的花的形状像一只只在向天堂祈祷的手掌,可是再也没有在这个城市出现过.每年的秋彼岸期间(春分前后三天叫春彼岸,秋分前后三天叫秋彼岸)她会开在黄泉路上,曼珠和沙华的每一次转世在黄泉路上闻到彼岸花的香味就能想起前世的的自己,然后发誓不分开,但只有在这一刻,因为他们会再次跌入诅咒的轮回,灵魂籍由着这花的指引,走向幽冥……

而为了纪念这个美丽而又忧伤的传说,Linux内核中引入了守护进程,也正是与这个传说对应,守护进程也叫内核精灵,当然,如果你觉得人们都太迷信,而你是共产党员,是无神论者,那么ok,你可以叫它为内核线程.事实上我也是无神论者,不过我只敢在白天承认这一点.我们来看具体的代码.

801,调用了kernel_thread()函数,kernel_thread(usb_stor_control_thread, us, CLONE_VM),并将返回值用一个整型变量p来表示,如果从前您对内核本身不是很熟悉,那这个函数就会让您有点头疼了.这个函数将会创建一个内核线程,而函数usb_stor_control_thread()将会执行,us将是传递给她的参数,CLONE_VM只是设定的一个flag,Linux内核不是很熟悉的话,可以将kernel_thread看作类似于fork的冬冬,什么?fork您也不知道?好吧.不知道就不知道,只是依稀记得在那毕业求职的日子里,很多外企的笔试面试中都会问起fork,问一些关于她的返回值的问题,印象中,2004年维尔软件的校园招聘笔试中考过,后来我去Sun中国工程研究院面试也被问起过. 实际上,简单一点说,kernel_thread()这么一执行呢,就会有两个进程,一个是父进程,一个是子进程,子进程将会执行usb_stor_control_thread(),us是作为usb_stor_control_thread函数的参数(实参),CLONE_VM标志表征父子进程之间共享地址空间,执行完usb_stor_control_thread()之后,子进程就结束了,她会调用exit()函数退出.而父进程继续顺着usb_stor_acquire_resources()函数往下走,kernel_thread()函数对于父进程而言返回的是子进程的进程id,所以802行先判断,若是返回值p小于0,则说明出错了,否则,那就把p赋给us的元素pid.

于是,咱们接下来必须再次兵分两路,分别跟踪父进程和子进程前进了.先看父进程,810,执行wait_for_completion(&(us->notify)),如果您说wait_for_completion是谁?您早已经把她忘怀,那么她会很伤心的.记得咱们当初在提交urb的时候调用过她吗?咱们初始化了一个等待队列,urb->done,然后咱们提交了urb,然后咱们通过调用wait_for_completion(&urb->done)进入了等待,进入了睡眠,urbusb core处理完了,或者说被urb host controller处理完了,complete()函数将会被调用,从而唤醒咱们那个进入睡眠的进程.所以此处也一样,us->notify是在很早很早以前storage_probe()函数中初始化的,该函数的945,init_completion(&(us->notify)),struct us_data,有这么一个元素notify,struct completion结构体变量,所以在这里,父进程将进入睡眠,谁来唤醒他?没错,您很聪明,正是子进程,也正是在usb_stor_control_thread()函数中,会有complete(&(us->notify))这么一句,wait_for_completion()complete()是一对青梅竹马的函数,她们总是一起被用,一个设置进程进入睡眠,另一个则负责把这个进入睡眠的进程唤醒,如果您知道信号量的话,她们就类似于信号量中的down()/up()函数对,只不过她们更加安全.

,父进程先搁一搁,反正他进入睡眠了,没人唤醒他的话,他是不会往下走的.来看子进程,也就是usb_stor_control_thread()函数,这个函数定义于drivers/usb/storage/usb.c.咱们下一节再深入这个函数,现在,休息,休息一会...

抱歉!评论已关闭.