许多常见的文件系统不提供原子操作,但是在某些情况下以原子方式写入文件非常重要。我试图为这个问题提出解决方案。
我做了以下假设:
这就留下了以下问题:写入文件时,程序可能会中断,并且文件中只剩下部分内容要写入。
我提出以下过程:
新建文件和备份文件与原始文件是有区别的(例如,它们的前缀可以不同,或者可以在同一卷上的单独目录中)。同时,它们的名称应直接映射到相应的原始名称(例如,只需使用相同的文件名)。
但是,这还不能使操作原子化。该过程可能会中断步骤1、2、3或4:
使用先前的假设2和3,程序必须在崩溃后重新启动。在启动过程中,它应执行以下恢复检查:
仅使用原子操作的恢复过程本身将在中断后继续从中断处继续进行。
我相信这个想法可以确保对单个程序进行原子写入。这些问题仍然存在:
可以通过使用策略(例如,检查其他实例,并拒绝对其他用户的目录访问)来解决这些问题(先前的假设未包括在内)。
最后,我的问题是:这样做有意义吗,或者过程中存在缺陷?是否有任何问题阻止这种方法在实践中使用?
基于这个主题,我提出了一个有趣的Singleton模式版本,该实现基于AtomicIntegers.
问题是:
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) 我写了一个基于向量的小型轻量级推/弹队列(想象它应该很快),如下所示:
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)
矢量的大小应该是已知的,我想知道为什么它不是线程安全的?在什么情况下这会弄乱我的结构?
我希望一个接一个地运行许多Lua脚本,而不允许任何命令在其间运行.我还需要将第一个脚本的结果传递给第二个脚本,等等.
我把所有脚本放在一个文件中,暂时解决了这个问题.但是,第二个脚本会修改第一个脚本返回的键.因此,将所有内容放在一个文件中会违反EVAL命令语义,因为第二个脚本使用的所有键都应使用KEYS数组传递.
在标题中,是关于uint8,atomic的读写操作吗?从逻辑上讲,它必须是单个cpu指令,显然是为8位变量进行读写.但无论如何,两个内核可以同时从内存中读写,是否有可能以这种方式创建过时的数据?
是否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) OpenCL和CUDA已经包含了几年的原子操作(尽管显然不是每个CUDA或OpenCL设备都支持这些).但是 - 我的问题是由于非原子写作而与"生活在一起"比赛的可能性.
假设网格中的多个线程都写入全局内存中的相同位置.我们是否保证,当内核执行结束时,其中一个写入的结果将出现在该位置,而不是一些垃圾?
这个问题的相关参数(选择任何组合,编辑除了已经得到答案的nVIDIA + CUDA):
是否有一种简单的方法可以原子方式读取值,然后使用StackExchange c#驱动程序从Redis中删除它?
我在Redis中缓冲项目,当它们达到某个阈值时我会检索它们,但我也想刷新我的缓冲区.我需要提一下,我将项目存储在列表中,并通过"刷新缓冲区",我的意思是我要删除列表.
"关键":[项目清单]
在下面的代码中,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) 我找到了以下代码,输出总是:
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)
我不明白第二个结构专用原子类型怎么能锁定自由而第一个专用原子类型不能无锁?
提前致谢.
atomicity ×10
c++ ×3
c# ×2
c++11 ×2
redis ×2
atomic ×1
concurrency ×1
cuda ×1
eval ×1
file-io ×1
filesystems ×1
go ×1
interlocked ×1
java ×1
lua ×1
memory-model ×1
opencl ×1
pointers ×1
singleton ×1
transactions ×1
uint ×1