我正在写一个 randomAnimalGenerator。它是一个多线程C程序,使用VS2010,适用于Windows X64,将用于为动物园随机生成动物。
我怎样才能让不同的线程都安全地写入全局结构(“zoo”)的成员,而不用对 zoo 结构实现锁定?这 全局结构的值将始终只会递增 (++),而不会递减 (--)。在下面的代码中,在不使用 OMP 的情况下,狮子、老虎和熊各自的正确值为 45,000。但是使用并行循环,值不等于 45,000。
有没有办法让 Openmp 将这些写入调度到同一个变量,而不会弄乱制作结构的私有(private)版本?
#define LIONS 1
#define TIGERS 2
#define BEARS 3
// global struct
struct
{
int lions;
int tigers;
int bears;
} zoo;
void addAnimalsToZoo(void)
{
int animalType = randomAnimalGenerator();
if (animalType == LION)
++zoo.lions;
else
if (animalType == TIGER)
++zoo.tigers;
else
if (animalType == BEAR)
++zoo.bears;
else
printf("unknown animal type generated\n");
}
void myZooMaker(void)
{
#pragma omp parallel for
for (int i = 0; i < 45000; ++i)
addAnimalsToZoo();
}
最佳答案
如果不进行重大重构,您的程序将无法正常运行。如前所述,该程序展示了规范的数据竞争,多个线程在没有协调的情况下同时更新共享数据结构。
你可以:
- 从结构中删除变量
lions
、tigers
和bears
(稍后我会解释原因)。 - 修改
randomAnimalGenerator
以适当的概率返回其中一只动物。
然后,这是近似值,因为我不是 C 程序员,按照这些行重写
int lions;
int tigers;
int bears;
lions = 0;
tigers = 0;
bears = 0;
#pragma omp parallel for default(shared) private(i) reduction(+:lions, +:tigers, +:bears)
for (int i = 0; i < 45000; ++i)
{
int newAnimal;
newAnimal = randomAnimalGenerator();
if (newAnimal==LION) ++lions;
if (newAnimal==TIGER) ++tigers;
if (newAnimal==BEAR) ++bears;
}
最后,变量 lions
、tigers
和 bears
的总和应为 45000
。请注意减少子句的使用和默认可访问性声明为 shared
。 OpenMP 缩减不能应用于结构的元素或整个结构,这就是我放弃 zoo
的原因。
我不保证代码是正确的,但你应该明白了。
关于c - 如何使用不同的线程使用openmp安全地更新C结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20407226/