标签: atomicity

在非事务性文件系统中实现原子文件写入

许多常见的文件系统不提供原子操作,但是在某些情况下以原子方式写入文件非常重要。我试图为这个问题提出解决方案。

我做了以下假设:

  • 使用中的文件系统支持inode级别的原子操作(例如NTFS)。这意味着移动删除是原子的。
  • 只有程序本身才能访问文件。
  • 一次只有一个程序实例,它以单线程方式运行。
  • 为简单起见,每次都写入整个文件内容(即截断写入)。

这就留下了以下问题:写入文件时,程序可能会中断,并且文件中只剩下部分内容要写入。

我提出以下过程:

  1. 写新的内容到一个临时文件
  2. 将原始文件“ 原始”移动到一个临时位置备份
  3. 移动
  4. 删除备份

新建文件和备份文件与原始文件是有区别的(例如,它们的前缀可以不同,或者可以在同一卷上的单独目录中)。同时,它们的名称应直接映射到相应的原始名称(例如,只需使用相同的文件名)。

但是,这还不能使操作原子化。该过程可能会中断步骤1、2、3或4:

  1. 留下一个可能不完整的New
  2. 移动是原子的,但是现在缺少目标文件。这两个新的备份存在并且是完整的。
  3. Move是原子的,但是有一个未使用的Backup。在被替换的内容
  4. 删除是原子的。

使用先前的假设2和3,程序必须在崩溃后重新启动。在启动过程中,它应执行以下恢复检查:

  • 如果 存在“ 新建”,但“ 备份”不存在,则在步骤1或之后崩溃。删除“ 新建”,因为它可能不完整。
  • 如果存在“ 新建”并且“ 备份”也存在,那么我们在步骤2之后崩溃。继续执行步骤3。
  • 如果备份存在,但新的不也一样,我们一步后坠毁3.第4步继续。

仅使用原子操作的恢复过程本身将在中断后继续从中断处继续进行。

我相信这个想法可以确保对单个程序进行原子写入。这些问题仍然存在:

  • 当使用同一程序的多个实例时,恢复过程会干扰其他程序中当前正在进行的文件写入。
  • 仅读取但不写入的外部程序通常会获得正确的结果,但是如果同时对请求的条目执行写操作,则它们可能会错误地找不到任何条目。

可以通过使用策略(例如,检查其他实例,并拒绝对其他用户的目录访问)来解决这些问题(先前的假设未包括在内)。

最后,我的问题是:这样做有意义吗,或者过程中存在缺陷?是否有任何问题阻止这种方法在实践中使用?

filesystems file-io transactions atomicity

4
推荐指数
1
解决办法
1576
查看次数

这个Singleton是一个线程安全的吗?

基于这个主题,我提出了一个有趣的Singleton模式版本,该实现基于AtomicIntegers.

问题是:

  • 这个实现是正确的和线程安全的,通常可以使用Atomic Variables进行线程同步和管理吗?
  • 附加问题:如果这个实现是线程安全的,我真的需要一个volatile实例变量的修饰符吗?
public class StrangeSingleton
{

    private StrangeSingleton() {};

    private static volatile Object instance;

    private static AtomicInteger initCounter = new AtomicInteger();
    private static AtomicInteger readyCounter = new AtomicInteger();

    static Object getInstance()
    {

        if (initCounter.incrementAndGet() == 1)
        {
            instance = new Object();

            readyCounter.incrementAndGet();

            return instance;
        }
        else if (readyCounter.get() == 1)
        {
            return instance;
        }
        else
        {
            //initialization not complete yet.
            //write here some logic you want:               
            //sleep for 5s and try one more …
Run Code Online (Sandbox Code Playgroud)

java concurrency singleton multithreading atomicity

4
推荐指数
1
解决办法
793
查看次数

正确使用原子

我写了一个基于向量的小型轻量级推/弹队列(想象它应该很快),如下所示:

template <typename T> class MyVectorQueue{

public:

    MyVectorQueue (size_t sz):my_queue(sz),start(0),end(0){}

    void push(const T& val){
       size_t idx=atomic_fetch_add(&end,1UL);
       if (idx==my_queue.size())
          throw std::runtime_error("Limit reached, initialize to larger vector");
       my_queue[idx]=val;
    }

    const T& pop(){
        if (start==end) 
           return end__;
        return my_queue[start.fetch_add(1UL)];
    }

    size_t empty()
    {
        return end==start;
    }

    const T& end() {
        return end__;
    }

private:
    T end__;
    std::atomic<size_t> start,end;
    std::vector<T> my_queue;    
}; 
Run Code Online (Sandbox Code Playgroud)

矢量的大小应该是已知的,我想知道为什么它不是线程安全的?在什么情况下这会弄乱我的结构?

c++ multithreading atomicity c++11

4
推荐指数
1
解决办法
300
查看次数

如何从Redis中的脚本调用脚本?

我希望一个接一个地运行许多Lua脚本,而不允许任何命令在其间运行.我还需要将第一个脚本的结果传递给第二个脚本,等等.

我把所有脚本放在一个文件中,暂时解决了这个问题.但是,第二个脚本会修改第一个脚本返回的键.因此,将所有内容放在一个文件中会违反EVAL命令语义,因为第二个脚本使用的所有键都应使用KEYS数组传递.

lua eval atomicity redis

4
推荐指数
1
解决办法
1088
查看次数

是否在golang atomic中对uint8进行读写?

在标题中,是关于uint8,atomic的读写操作吗?从逻辑上讲,它必须是单个cpu指令,显然是为8位变量进行读写.但无论如何,两个内核可以同时从内存中读写,是否有可能以这种方式创建过时的数据?

go atomicity uint

4
推荐指数
2
解决办法
2187
查看次数

Interlocked.Read/Exchange for longs on 64-bit 体系结构

是否Interlocked.Read(ref long)在 64 位架构上进行了“优化”?即如果我正在编写一个可以被两种架构使用的库,我是否应该担心Interlocked.Read在 64 位 CPU 上不必要地使用性能影响?

我想过使用这样的东西,所以我想知道这是否有意义:

    // X64 is a preprocessor constant set for x64 builds  

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static long Read(ref long address)
    {
#if X64
        // atomic on 64-bit processors
        return address;
#else
        // if I got it right, this creates a full memory barrier
        return Interlocked.Read(ref address);
#endif
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void Write(ref long address, long value)
    {
#if X64
        // atomic on 64-bit processors
        address = value;
#else
        // …
Run Code Online (Sandbox Code Playgroud)

c# multithreading interlocked atomicity

4
推荐指数
1
解决办法
646
查看次数

对GPU上的非原子写入的弱保证?

OpenCL和CUDA已经包含了几年的原子操作(尽管显然不是每个CUDA或OpenCL设备都支持这些).但是 - 我的问题是由于非原子写作而与"生活在一起"比赛的可能性.

假设网格中的多个线程都写入全局内存中的相同位置.我们是否保证,当内核执行结束时,其中一个写入的结果将出现在该位置,而不是一些垃圾?

这个问题的相关参数(选择任何组合,编辑除了已经得到答案的nVIDIA + CUDA):

  • 内存空间:仅限全局内存; 这个问题与本地/共享/私人记忆无关.
  • 对齐:在单个存储器写入宽度内(例如,nVIDIA GPU上的128位)
  • GPU制造商:AMD/nVIDIA
  • 编程框架:CUDA/OpenCL
  • 存储指令在代码中的位置:所有线程/不同代码行的相同代码行.
  • 写入目标:固定地址/固定偏移量与功能参数的地址/完全动态
  • 写宽度:8/32/64位.

cuda atomic memory-model opencl atomicity

4
推荐指数
1
解决办法
158
查看次数

使用StackExchange.Redis从Redis进行原子读取和删除

是否有一种简单的方法可以原子方式读取值,然后使用StackExchange c#驱动程序从Redis中删除它?
我在Redis中缓冲项目,当它们达到某个阈值时我会检索它们,但我也想刷新我的缓冲区.我需要提一下,我将项目存储在列表中,并通过"刷新缓冲区",我的意思是我要删除列表.
"关键":[项目清单]

c# atomicity redis stackexchange.redis

4
推荐指数
1
解决办法
4160
查看次数

从C++中的另一个线程读取指针

在下面的代码中,x由于原子线程围栏,线程2中的值将始终为10.

int x;
atomic<bool> b(false);

// thread 1:
x = 10;
atomic_thread_fence(memory_order_release);
b = true;

// thread 2:
while(!b){}
atomic_thread_fence(memory_order_acquire);
assert(x == 10); // x will always be 10
Run Code Online (Sandbox Code Playgroud)

但是在下面的代码中,*x线程2中的总是10?

int* x = new int;
atomic<bool> b(false);

// thread 1:
*x = 10;
atomic_thread_fence(memory_order_release);
b = true;

// thread 2:
while(!b){}
atomic_thread_fence(memory_order_acquire);
assert(*x == 10); // will *x always be 10?
Run Code Online (Sandbox Code Playgroud)

c++ multithreading pointers atomicity

4
推荐指数
1
解决办法
615
查看次数

结构专用原子类型如何可以自由锁定?

我找到了以下代码,输出总是:

std::atomic<A> is lock free? false
std::atomic<B> is lock free? true
Run Code Online (Sandbox Code Playgroud)

这是代码:

struct A { int a[100]; };
struct B { int x, y; };
int main()
{
    std::cout << std::boolalpha
              << "std::atomic<A> is lock free? "
              << std::atomic<A>{}.is_lock_free() << '\n'
              << "std::atomic<B> is lock free? "
              << std::atomic<B>{}.is_lock_free() << '\n';
}
Run Code Online (Sandbox Code Playgroud)

我不明白第二个结构专用原子类型怎么能锁定自由而第一个专用原子类型不能无锁?

提前致谢.

c++ multithreading atomicity c++11

4
推荐指数
1
解决办法
193
查看次数