简体   繁体   English

如何在不阻塞的情况下保护非原子变量不被中断和应用程序代码修改

[英]How to protect a non-atomic variable from modification by both interrupt and application code without blocking

I want to be able to modify a non-atomic variable in interrupt context or application context without ever blocking.我希望能够在不阻塞的情况下修改中断上下文或应用程序上下文中的非原子变量。 To prevent the ISR from blocking, I use an atomic flag to guard the non-atomic data.为了防止 ISR 阻塞,我使用原子标志来保护非原子数据。

#include <atomic>
#include <cstdint>

using CountLock = std::atomic<bool>;
static_assert(CountLock::is_always_lock_free, "count lock must be lock free");

#define TARGET_COUNT (1000)
CountLock count_locked{false};
uint64_t  count{0}; // non-atomic on 32-bit system

// In interrupt
void MyISR()
{
    // Don't modify count if locked
    if (count_locked)
        return;

    ++count; // non-atomic

    if (count == TARGET_COUNT)
        // Do something
}

// Application code (not in interrupt)
void setCount(uint64_t newCount)
{
    // lock count while we are setting it
    count_locked = true;
    count = newCount;
    count_locked = false;
}
  1. Does this correctly guard the data?这是否正确保护数据?
  2. Is the compiler allowed to compile out the count_locked variable or reorder instructions such that the data is outside the lock?是否允许编译器编译出 count_locked 变量或重新排序指令,以便数据在锁之外?
  3. Am I correct in thinking nothing needs to be marked volatile?我认为没有什么需要标记为 volatile 是否正确?
  4. Is this equivalent to a mutex?这相当于互斥锁吗?

Consider two threads concurrently calling MyISR and setCount respectively:考虑两个线程同时分别调用MyISRsetCount

T1                             T2

if (count_locked)
        return;

                               count_locked = true;

 ++count; /*non-atomic*/       count = newCount;        // << data race

 if (count == TARGET_COUNT)
    // Do something

                               count_locked = false;

The atomic does not protect writes to count .原子不保护对count写入。

  1. No

  2. The data is modifed without being properly locked anyhow数据被修改而没有被正确锁定

  3. Yes.是的。 Quoting from When to use volatile with multi threading?引用何时在多线程中使用 volatile? : "volatile is (nearly) useless for platform-agnostic, multithreaded application programming." :“对于平台无关的多线程应用程序编程,易失性(几乎)是无用的。”

  4. No

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM