gpt4 book ai didi

c - 在 macOS 内核扩展中有效地使用同步

转载 作者:行者123 更新时间:2023-12-01 13:28:47 24 4
gpt4 key购买 nike

我在我的 macOS 内核扩展中使用同步 KPI 来验证一个函数是否在另一个函数启动之前完全执行(当然这两个函数是在不同的线程中执行的)。

这些是同步方法:

msleep(void *channel,lck_mtx_t *mtx,int priority,const char *wmesg,  struct  timespec *timeout);
wakeup(void *channel);

因此 channel 是一个指向 bool 值的指针,表示第一个函数已完全执行。

这是我在第一个函数中的实现:

OSIncrementAtomic(channel);
wakeup(channel);

在另一个函数中,我等待 channel 被设置:

msleep(channel, NULL, 0, "", ts);

但是,如果第一个函数在第二个函数之前终止(这是常见的情况),我会在 ts 中等待 vein 的超时。

我的问题是,如果 wakeup 已经发生,是否有办法跳过 msleep

谢谢,

最佳答案

msleep 的使用有两个问题。

首先,channel是一个不透明的值,不是“指向 bool 值的指针”;你不增加它,它不会被调用修改。相反,您只需确保它是唯一的,即不被其他不相关的 msleep 调用使用。约定是使用一个相关数据结构的内存地址来实现唯一性。如果在您的情况下您不能确保在 wakeup 之前调用 msleep,那么您将使用 Mach semaphore ,而不是 msleep/wakeup

另一个问题是,正如@mrdvlpr 已经在评论中指出的那样,msleep 需要一个互斥锁才能唤醒。如果您使用 mtx=NULL 调用它,它将无限期休眠并且在同一 channel 上调用 wakeup 将不会有任何效果。如果您想稍后使用 wakeupwakeup_once 唤醒,您需要提供一个有效且锁定的互斥量而不是 NULL

在 XNU 中对 msleep 的最小但功能调用没有超时看起来像这样:

lck_grp_t *lck_grp;
lck_mtx_t *lck_mtx;

lck_grp = lck_grp_alloc_init("com.example.mslpex", LCK_GRP_ATTR_NULL);
if (!lck_grp)
/* handle failure */
lck_mtx = lck_mtx_alloc_init(lck_grp, LCK_ATTR_NULL);
if (!lck_mtx)
/* handle failure */

/* ... */

lck_mtx_lock(lck_mtx);
error = msleep(channel, lck_mtx, pri|PDROP, "mslpex", NULL);
if (error)
/* handle failure */
else
/* handle success */

/* ... */

lck_mtx_free(lck_mtx, lck_grp);
lck_grp_free(lck_grp);

相应的唤醒电话很简单:

wakeup(channel);

为了系统稳定性,您可能希望在调用 msleep 时使用超时,以便从 wakeup 未按预期调用的情况下恢复。

关于c - 在 macOS 内核扩展中有效地使用同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47056457/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com