Linux下如何写可重启的多线程子系统

目标:在内核中加入一个RPC子系统,对内核其他子系统提供三个服务函数:
rpc_init()
do_rpc_service()
rpc_exit()
要求在如下情形下能够正常工作:
while(!should_stop)
{
    rpc_init()
    do_rpc_service()
    rpc_exit()
}

在rpc子系统启动后,会建立很多线程,这些线程可能各自处于不同状态,比如等待信号(sema),等待时间片(schedule()),正在运行等等。如何让我们的线程从这么多状态中听从rpc_exit()的召唤纷纷退出呢?加入do_rpc_service()中有这么一个线程,正在做如下工作:
do{
    schedule();
}while(not_ready);
除非我们能够改变not_ready的状态,使得其为false,否则这个循环不可能终止。这样,这个线程也无法退出,最后导致rpc_exit()语义失败。

为了让线程能够正常终止,有两种方法解决:
1、去改变那些比如not_ready之类的变量值
2、避免编写这样的代码,用轮询的方法取而代之

首先看第一种方法,rpc_exit需要知道系统中到底有多少地方使用了条件变量循环,以逐一改变这些变量状态。同时,还要注意循环之后的代码执行。由于是退出,所以其后很多逻辑都应该不再执行。显然,这个工程有点大…

再看第二种方法,由于采用了轮询,可以在每次轮询中检查程序执行状态变量,一旦为rpc_stopped,则中断执行。如何避免编写上文提到的循环呢?首先,自己不要写这样的代码,其次,不可以调用wait_for_completion, down()之类的函数,取而代之调用down_interruptible()这样的可中断的函数,因为这样的函数能够被信号中断,退出while循环。

后面计划对rpc子系统进行改写,使得其符合条件2.

发表评论

邮箱地址不会被公开。 必填项已用*标注