簡體   English   中英

如何在不阻塞的情況下保護非原子變量不被中斷和應用程序代碼修改

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

我希望能夠在不阻塞的情況下修改中斷上下文或應用程序上下文中的非原子變量。 為了防止 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. 這是否正確保護數據?
  2. 是否允許編譯器編譯出 count_locked 變量或重新排序指令,以便數據在鎖之外?
  3. 我認為沒有什么需要標記為 volatile 是否正確?
  4. 這相當於互斥鎖嗎?

考慮兩個線程同時分別調用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;

原子不保護對count寫入。

  1. 數據被修改而沒有被正確鎖定

  2. 是的。 引用何時在多線程中使用 volatile? :“對於平台無關的多線程應用程序編程,易失性(幾乎)是無用的。”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM