【发布时间】:2021-09-19 04:51:56
【问题描述】:
我觉得这个问题的核心和我使用的具体语言和库无关,所以我使用了一些伪代码。我们可以假设 C 是一种语言和一个 WinApi COM DLL。
假设我正在使用一个动态链接的外部库,它公开了一些回调以响应某些事件。说:
function RegisterCallback(ptr *callback);
用作:
function OnEvent(type newValue) {
...
}
...
RegisterCallback(&OnEvent)
...
库告诉我回调应该是非阻塞。 现在,假设我想更新一个内部状态来响应这个事件。此内部状态由其他线程访问,因此由 mutex 保护。因此我想写:
function OnEvent(type newValue) {
mutexLock();
internalState = newState;
mutexUnlock()
}
但是,这将是一个潜在的阻塞操作。我应该如何进行?我看到的唯一解决方案是使用不同的线程来更新状态,例如:
function OnEvent(type newValue) {
sendChangeStateMessage(newValue)
}
但是,同样,为了让这个调用是非阻塞的,这个“发送操作”应该被缓冲(即,有一个消息队列),因为跨线程发送(即共享数据)需要同步,并且因此锁定。
编辑:当然,如果操作是原子的(可能是整数),则没有这样的问题 /EDIT
总结一下:如何将阻塞代码转换为非阻塞代码?
谢谢
【问题讨论】:
-
这最终是 C++20 协程解决的问题。如果您需要在 C 中实现这一点,您将不得不重新实现协程。
-
没有什么需要改变的。代码不等待回调中的某些东西
-
@RbMm 见答案下方的评论
标签: multithreading winapi callback blocking nonblocking