c - 如何在多线程上下文中初始化静态变量?

标签 c windows multithreading static-initialization

我想到了在函数中很好地使用 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/

相关文章:

windows - CMD shell 中的可用空间

c++ - 打开转义文件时出现意外行为 :///URL in IE

c - pthread 和有点 "broadcast stream"

c# - 任务<T>保留启动参数

c - 将二进制图像从 matlab 导入到 "C"程序

c - 指针运算,意外结果

c - 带 while 循环的读取命令函数

字符指针和 printf 函数

windows - 处理公司防火墙添加自签名证书

c# - 阻塞监听防止断开连接