避免 Android 原生代码 (C++) 中的竞争条件
avoid race condition in android native code (C++)
问题:在同一个无符号int变量上执行按位操作(清除两个不同的位位置(的两个线程正在创建竞争条件。(它是一个标志变量(。
目前正在尝试的解决方案:每次在设置或清除位位置之前使用互斥锁。
环境:安卓用户空间,仿生,C++
现在,我也想检查一下,我是否可以避免使用android的原子操作函数的竞争条件, android_atomic_and/android_atomic_or
并将变量定义为 volatile unsigned int
。这在逻辑上类似于内核空间原子操作,如atomic_set
,atomic_and
根据我的理解。
因此,如果有人可以消除我的疑虑,或者如果其他解决方案可以更好地解决此问题,请提供帮助。
这个问题一如既往地有许多不同的解决方案。在大多数系统上,基本整数运算通常是原子的。但是您必须确保变量没有缓存,并且基本操作可以在一个步骤中完成。因此,将整数设置为 0 将是一个基本操作。但是,将它的价值增加一,或者在某处改变一点不是。因为在那里你正在读取当前状态,计算新的状态,最后把它写回来。另一个线程同时执行相同的操作会导致不一致的状态。(例如,一个变量增加了两次,但它的值只多了一个(
一种解决方案是用锁包围对此整数的访问。
另一种更快的方法是使用compare_and_set的写作方法。(阅读应该没问题(在这种情况下,请确保您的变量未缓存在其中一个 CPU 中,例如,通过声明其可变性。这可能对您有所帮助;
bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)
type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...)
These builtins perform an atomic compare and swap. That is, if the current value of *ptr is oldval, then write newval into *ptr.
The “bool” version returns true if the comparison is successful and newval was written. The “val” version returns the contents of *ptr before the operation.
我从这里有这部分:http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html
使用比较和正确设置,您可以确保仅在没有其他人同时修改变量的情况下对其进行修改。因此,您需要在 while 循环中使用它,如以下线程所示:如何在 ARM7 中原子比较和交换?
第三种方法是前往一个库,它为您提供了一长串不同的"原子操作"。这可能是最干净的方法。使用易失性和比较设置自己进行处理可能是危险的,因为如果变量的特殊处理被遗忘在某个地方,它不会警告您或其他人。
最后一件事。请注意,不受保护的读取访问权限仅适用于单个整数变量。如果使用双精度或两个整数,则可能会得到不一致的状态。在写入进程 0 期间,当您在线程 1 中读取双精度变量时,双精度变量的一半(或 2 的一个整数(已经具有新值,另一部分仍然是旧值。这将直接导致难以找到的错误。很少发生,但当它发生时,灾难。(此部分仅适用于常见的 32 位 CPU 系统。某些较小的系统可能会以较小的块处理内存。另一方面,64位系统通常将两个整数(64位(处理为一个块,在那里它可以与双精度一起使用,但不适用于更大的结构(
祝你好运!
- compare_exchange C++函数如何确定竞争条件?
- 在C++中写入相同值的竞争条件?
- QByteArray 通过队列连接按值发出并连接并附加到竞争条件?
- 从stdin读取时子进程挂起(fork/dup2竞争条件)
- 如何修复条件变量等待/通知的竞争条件
- 在没有互斥锁的情况下重新计数时如何避免竞争条件?
- 替代 rand() 以避免竞争条件?
- CUDA 内核中的竞争条件
- 为什么跨线程更改共享变量的代码显然没有受到竞争条件的影响
- 类声明自己(*this)为private以避免竞争条件/放弃在gcc中对threadprivate的请求
- 使用 gtest EXPECT_CALL 时竞争条件段错误,而另一个期望是执行相同的方法
- boost::进程间消息队列创建时的竞争条件
- 如何在没有竞争条件的情况下将 QFutureWatcher 与 QtConcurrent::run() 一起使用
- 为什么 printf 可以屏蔽竞争条件,而系统日志不能?
- 为什么这个代码会产生竞争条件
- 为什么 CUDA 同步点不能阻止竞争条件?
- 竞争条件:一个线程创建静态对象,另一个线程在初始化完成之前使用它.如何处理
- 如何使用 Boost Atomic 删除竞争条件
- boost::mutex 无法帮助避免C++程序中的竞争条件
- 类中的递归函数或竞争条件