避免 Android 原生代码 (C++) 中的竞争条件

avoid race condition in android native code (C++)

本文关键字:竞争 条件 C++ Android 原生 原生代 代码 避免      更新时间:2023-10-16

问题:在同一个无符号int变量上执行按位操作(清除两个不同的位位置(的两个线程正在创建竞争条件。(它是一个标志变量(。

目前正在尝试的解决方案:每次在设置或清除位位置之前使用互斥锁。

环境:安卓用户空间,仿生,C++

现在,我也想检查一下,我是否可以避免使用android的原子操作函数的竞争条件, android_atomic_and/android_atomic_or并将变量定义为 volatile unsigned int 。这在逻辑上类似于内核空间原子操作,如atomic_setatomic_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位(处理为一个块,在那里它可以与双精度一起使用,但不适用于更大的结构(

祝你好运!