集群系统MOSIX分析(7)
2008-12-01 11:04:48 来源:WEB开发网在用户空间向一个进程发送信号由系统调用sys_kill()实现。该函数调用函数kill_something_info(),它根据情况,或者向单个进程发送信号(kill_proc_info()),或者向一个进程组中的所有进程发送信号(kill_pg_info()), 最终都会调用函数send_sig_info()来完成真正的信号发送。kill_pg_info()中,通过for_each_local_task(p)来查找属于同组的进程。这是因为MOSIX中, 信号只会发给本地进程,而不会发送给REMOTE进程的。对于REMOTE进程,当通过kill()发送信号时,根据我们前面对系统调用的分析,我们知道最终将是由DEPUTY来调用sys_kill()。因此,信号是被挂入DEPUTY的task_struct结构中的pending队列里。
异步和强制信号的处理
内核也会向进程发送信号,例如当页面异常而又无法恢复时,do_page_fault()页面异常处理程序会通过force_sig()zx向当前进程发送一个SIGBUS信号。内核发送的信号一般都是需要立即作出反应的。MOSIX对系统发送信号的处理方式也和用户发送信号有所不同,内核发送的"强制"信号都保存在mosix_task的forced_sigs指针中。
我们首先看看函数force_sig_info()。如果信号的目的地为REMOTE进程,则:
如果处于中断服务中,则系统panic
得到进程已有的强制信号数(n= t->mosix.nforced_sigs)并试图分配内存(x = kmalloc((n + 1) * sizeof(siginfo_t), GFP_KERNEL))用于保存这n+1个信号信息
如果内存分配失败,则尽量再次发送该信号send_sig(sig, t, 0);返回0
因为分配内存返回时,可能已经处理了一部分信号,因此要进行检测。如果是,则释放刚刚申请的内存,跳到第二步
将保存的siginfo_t和新的info拷贝到分配的内存中,保存在mosix结构的forced_sigs中,并增加强制信号计数t->mosix.forced_sigs = x; t->mosix.nforced_sigs++;
我们前面已经分析过,REMOTE进程从系统空间返回到用户态之前,将会调用remote_pre_usermode_actions()函数。remote_pre_usermode_actions()函数将会检测当前进程是否有异步或"强制"信号待处理。如果有,它会通过函数transfer_signals_to_deputy()发送REM_ASIG请求将信号传递给DEPUTY处理【参见remote_pre_usermode_actions()】。DEPUTY则会通过函数deputy_analyse_remote_signals()来处理REM_ASIG请求。它首先从连接中获得"强制"信号信息,通过force_sig_info()向当前进程(即DEPUTY本身)发送强制信息。然后得到每个信号,依次处理,一般都是通过send_sig发给当前进程。
更多精彩
赞助商链接