我有一个必须在线程之间共享的数组,受信号量保护。我把初始化代码放在一个可以多次调用的函数中,一个“构造函数”,如下:
#include <stdbool.h> //for bool
#include <semaphore.h>
sem_t global_mutex;
char global_array[N]; // Protected with global_mutex
struct my_struct *new_my_struct(){
static bool is_init = false; // This will be initialized only once, right?
if (!is_init){ // 1
sem_init(&global_mutex, 0, 1); // 2
sem_wait(&global_mutex); // 3
if (!is_init){ // 4
is_init = true; // 5
... initialize global_array ... // 6
}
sem_post(&global_mutex); // 7
}
... proceed on the create and return a my_struct pointer ...
}
在理想情况下,线程将从 1 运行到 7,初始化数组并退出临界区。即使另一个线程在 2 中停止,在 4 中的测试也会是错误的,并且不会覆盖数组。我没有想过如果线程卡在 1 并重新初始化信号量会发生什么,但我相信只要is_init
由第一个运行的线程设置为 true 就不用担心了!
现在,如果一个线程在 4 处停止,而另一个线程从开始运行到完成,初始化并填充global_array
. 当线程停止在 4 运行时,它会重新初始化数组并删除第一个线程存储的状态。
我想知道是否有任何方法可以避免这种竞争条件(也许巧妙地使用static
?),或者我是否应该将初始化代码与构造函数分开并在没有并发的情况下在主线程中使用它。
这段代码正在使用中,我还没有遇到竞争状况。但是,据我所知,这是可能的,我希望纠正它。