gpt4 book ai didi

C 交换指针竞争条件

转载 作者:太空宇宙 更新时间:2023-11-04 03:36:53 25 4
gpt4 key购买 nike

我目前正在开发一个 C 程序,它或多或少是一个统一的(解)多路复用器,用户可以在其中创建输入和输出之间的映射。虽然目的地只保留一次并且对所有源都可用,但一个源可以在不同的组中存在一次或多次(但不能在同一组中出现两次)

无论如何,这是我的背景。为了让群组变得有用,我实现了一个根据用户输入切换群组的功能。

当前事件组由指针“activeGroup”保存。

每个输出目的地都有一个线程等待输入并检查事件组的映射,因此使用“activeGroup”指针。

我今天的测试环境使用了 ca。 2kHz 输入,而最终用户输入可能更高(例如 1000kHz,考虑到非事件源也可以发送数据)。没有明显的问题。

我现在的问题:

我应该为“activeGroup”指针使用 RWLock 吗?原子地简单交换指针是一个问题吗?通常我不介意一个或一百个输入包在短短的几分之一秒内到达错误的目的地,但如果读取线程在绝对最错误的时刻读取,我是否会以某种方式出现段错误?

唯一写入指针的函数:

bool activate_group(char *groupName){
... (get correct group to activate)
if(newActive){
if(activeGroup)
activeGroup->isActive = false;
// the only writing line to activegroup
activeGroup = grp;
grp->isActive = true;
return true;
}
return false;
}

访问它的两个函数之一(非常相似)

void forward_sender(...){

if(activeGroup && (input = FINDCORRECTINPUTSOUCEIN(activeGroup->mappingList)){

snd_params par;
par.sockfd = sockfd;
par.msg = buffer;
par.len = len;
sendMultipleByInput(activeGroup->mappingList, sender, &par);
}
}

另一个函数直接发送,这个可能发送多次。

如果 activeGroup 在两者之间切换,sendMultipleByInput 将不会发送,因为它不会在现在新的事件映射列表中找到设备之间的映射。

如果当前实现可能发生这种情况,我是否可以通过简单地访问 activeGroup 指针一次并将值复制到本地指针来避免这种情况?

我猜,如果有的话,那会把这种可能性降到最低?

由于性能是我程序的关键因素,我喜欢尽可能多的同步方法,这些方法可能会减慢速度甚至导致死锁(不太可能在这里使用 rwlock 更喜欢 writer,但仍然如此)

感谢您的任何见解

最佳答案

到目前为止还没有人回答,所以希望我能提供帮助。

要扩展死锁注释,请考虑经典示例...

T1: A -> B
T2: B -> A

只需将 T2 的顺序切换为...即可避免死锁(T1T2 都可以取得进展)

T2: A -> B

绝对不应该为了避免死锁而避免锁。不过,使用 rwlock 的直觉是正确的,因此最好还是尽量减少关键部分的范围。

锁的性能不应该是一个问题。大多数锁实现将避免进入内核。如果延迟真的是一个问题,那么有很多好的自旋锁实现。

不使用显式同步几乎肯定会导致不正确的行为。在大多数架构(尤其是 x86)上,写入指向内存的指针通常是一个原子操作,但未定义跨内核/处理器的读写顺序。

例如,在您的代码中...

bool activate_group(char *groupName){
... (get correct group to activate)
if(newActive){
if(activeGroup)
activeGroup->isActive = false;
// the only writing line to activegroup
activeGroup = grp;
grp->isActive = true;
return true;
}
return false;
}

和...

void forward_sender(...){

if(activeGroup && (input = FINDCORRECTINPUTSOUCEIN(activeGroup->mappingList)){

snd_params par;
par.sockfd = sockfd;
par.msg = buffer;
par.len = len;
sendMultipleByInput(activeGroup->mappingList, sender, &par);
}
}

有许多不同的有效内存顺序。特别是,没有什么可以保护 mappingListactiveGroup 之前被更新。实际顺序几乎与程序顺序无关。更重要的是,编译器总是会避免内存读写。因此,这些值很可能会保留在寄存器中,甚至不会接触内存。

!!!危险区域!!!

如果无锁编程是绝对必要的 C11 添加了无锁 atomics .但是,除非您完全理解各种内存排序排列,否则您几乎肯定会得到意想不到的行为。

关于C 交换指针竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31842230/

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