进程调度API之completion_done

bool completion_done(struct completion *x)
用于判断是否还有wait等待在completion *x 这个完成量上,然后true 表示没有等待,false 表示有wait在等待
其源码分析如下:
bool completion_done(struct completion *x)
{
	if (!READ_ONCE(x->done))
		return false;

	/*
	 * If ->done, we need to wait for complete() to release ->wait.lock
	 * otherwise we can end up freeing the completion before complete()
	 * is done referencing it.
	 *
	 * The RMB pairs with complete()'s RELEASE of ->wait.lock and orders
	 * the loads of ->done and ->wait.lock such that we cannot observe
	 * the lock before complete() acquires it while observing the ->done
	 * after it's acquired the lock.
	 */
	smp_rmb();
	spin_unlock_wait(&x->wait.lock);
	return true;
}
判断的核心是x->done 是否等于零。如果为零,则说明没有wait再等待了。
为什么这么说呢,因为完成量等待完成量的函数do_wait_for_common 中会对x->done 做减件操作
do_wait_for_common(struct completion *x,
		   long (*action)(long), long timeout, int state)
{
	if (x->done != UINT_MAX)
		x->done--;
	return timeout ?: 1;
}
而在释放完成量的函数complete 中会做加加操作
void complete(struct completion *x)
{
	unsigned long flags;

	spin_lock_irqsave(&x->wait.lock, flags);
	if (x->done != UINT_MAX)
		x->done++;
	__wake_up_locked(&x->wait, TASK_NORMAL, 1);
	spin_unlock_irqrestore(&x->wait.lock, flags);
}

并且这两者是可以嵌套配对的
所以当x->done 为零时,说明没有人操作完成量了.

在Linux系统,如果你正在使用`wait_for_completion_interruptible_timeout`函数等待一个`completion`结构体表示的任务完成,并且希望这个等待过程能够被外部断并结束睡眠状态,通常需要配合信号处理机制或者自定义的回调函数。 1. **设置信号处理**: - 首先,你需要在一个线程或进程注册一个信号处理器,比如SIGINT(Ctrl+C)或SIGHUP等。当收到这个信号时,你可以手动调用`complete(&your_completion)`来标记任务完成。 ```c static void signal_handler(int signum) { if (signum == SIGINT) { complete(&my_completion); } } // 注册信号处理器 register_signal(signal_handler, SIGINT); wait_for_completion_interruptible_timeout(&my_completion, YOUR_TIMEOUT); ``` 2. **使用回调**: - 可以将`completion`关联一个回调函数,当任务完成后自动调用该函数。例如,在`init_completion`设置: ```c struct completion my_completion; atomic_set(&my_completion.done, false); // 初始化为未完成 void on_completion() { atomic_set(&my_completion.done, true); wake_up(&my_completion); } complete_on(&my_completion, on_completion); wait_for_completion_interruptible_timeout(&my_completion, YOUR_TIMEOUT); ``` 当`on_completion`函数被调用时,`wait_for_completion_interruptible_timeout`会立即返回。 无论哪种方法,记得在完成任务的实际操作之后更新`completion`的状态,以便`wait_for_completion_interruptible_timeout`能够感知到任务已结束并退出睡眠。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值