我想到了在函数中很好地使用 static 关键字是这样的:
void threadSafeWrite(int *array, int writeIndex, int writeData){
static void *threadLock = Lock_create(); //in my code locks are void* to be cross-platform compatable
Lock_aquire(threadLock);
array[writeIndex] = writeData;
Lock_release(threadLock);
}
简而言之,这似乎是制作临界区的好方法。不过,我的问题是,如何以线程安全的方式初始化 threadLock?我担心这个例子的问题是锁会被分配多次,每个线程都会使用不同的锁。有想法该怎么解决这个吗?似乎是先有鸡还是先有蛋的问题。我想要一个同时适用于 pthreads 和 windows 线程的解决方案(或多个解决方案)。
编辑:我想要这个功能的原因是因为它提供了一种非侵入式的方式来测试在单线程或多线程(用于调试目的)运行一段代码时是否存在差异。
最佳答案
一种方法是使用全局锁来序列化初始化路径。但是,您需要一个 SMP 内存屏障上的可移植包装器;锁隐含的获取屏障不是不够的,因为它原则上允许编译器和/或 CPU 在获取锁之前缓存内存读取的结果。这是一个例子:
Lock global_init_lock; // Should have low contention, as it's only used during startup
void somefunc() {
static void *data;
static long init_flag = 0;
if (!init_flag) { // fast non-atomic compare for the fast path
global_init_lock.Lock();
read_memory_barrier(); // make sure we re-read init_flag
if (!init_flag)
data = init_data();
write_memory_barrier(); // make sure data gets committed and is visible to other procs
init_flag = 1;
global_init_lock.Unlock();
}
read_memory_barrier(); // we've seen init_flag = 1, now make sure data is visible
// ....
}
也就是说,我建议将锁放在数据上,而不是放在作用于数据的函数上。毕竟,您打算如何同步这样的读者?如果以后想对单独的数组使用单独的锁怎么办?如果您以后想编写其他函数来获取该锁怎么办?
关于c - 如何在多线程上下文中初始化静态变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4767673/