TASK_KILLABLE:Linux 中的新进程状态(2)
- UID
- 1066743
|
TASK_KILLABLE:Linux 中的新进程状态(2)
NFS 客户机代码中的变化NFS 客户机代码也使用了这种新进程状态。清单 3 显示了 Linux 内核 2.6.18 和 2.6.26 在 nfs_wait_event 宏方面的差异。
清单 3. nfs_wait_event 因 TASK_KILLABLE 而发生的变化 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| Linux Kernel 2.6.18 Linux Kernel 2.6.26
========================================== =============================================
#define nfs_wait_event(clnt, wq, condition) #define nfs_wait_event(clnt, wq, condition)
({ ({
int __retval = 0; int __retval =
wait_event_killable(wq, condition);
if (clnt->cl_intr) { __retval;
sigset_t oldmask; })
rpc_clnt_sigmask(clnt, &oldmask);
__retval =
wait_event_interruptible(wq, condition);
rpc_clnt_sigunmask(clnt, &oldmask);
} else
wait_event(wq, condition);
__retval;
})
|
清单 4 显示了 nfs_direct_wait() 函数在 Linux Kernels 2.6.18 与 2.6.26 中的定义
清单 4. nfs_direct_wait() 因 TASK_KILLABLE 而发生的变化1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| Linux Kernel 2.6.18
=================================
static ssize_t nfs_direct_wait(struct nfs_direct_req *dreq)
{
ssize_t result = -EIOCBQUEUED;
/* Async requests don't wait here */
if (dreq->iocb)
goto out;
result = wait_for_completion_interruptible(&dreq->completion);
if (!result)
result = dreq->error;
if (!result)
result = dreq->count;
out:
kref_put(&dreq->kref, nfs_direct_req_release);
return (ssize_t) result;
}
Linux Kernel 2.6.26
=====================
static ssize_t nfs_direct_wait(struct nfs_direct_req *dreq)
{
ssize_t result = -EIOCBQUEUED;
/* Async requests don't wait here */
if (dreq->iocb)
goto out;
result = wait_for_completion_killable(&dreq->completion);
if (!result)
result = dreq->error;
if (!result)
result = dreq->count;
out:
return (ssize_t) result;
}
|
要了解 NFS 客户机中的更多变化,以便于更好地掌握这种新功能,请参阅 一节中的 Linux Kernel Mailing List 条目。
早期的 NFS 挂载选项 intr 可以帮助解决 NFS 客户机进程中断并等待某些事件的问题,但它允许所有中断,而不仅仅是通过致命信号(如 TASK_KILLABLE)。
结束语 尽管此特性是对现有选项的改进 — 毕竟,它是解决死进程的另一种方法 — 但它要得到普遍应用还有待时日。记住,除非真的非常有必要 禁止显式唤醒呼叫(通过传统的 TASK_UNINTERRUPTIBLE)之外的任何中断,否则请使用新的 TASK_KILLABLE。 |
|
|
|
|
|