我正在写一个randomAnimalGenerator。它是一个多线程的C程序,使用VS2010,用于Windows X64,将用于为动物园随机生成动物。
如何使不同的线程安全地写入全局结构(“zoo”)的成员,而不在动物园结构上实现锁定?该 全局结构的值将始终仅递增(++),而不递减( - )。在下面的代码中,不使用OMP,狮子,老虎和熊每个正确地具有45,000的值。但是使用并行循环时,值不等于45,000。
有没有办法让Openmp将这些写入计划到同一个变量而不会搞乱制作该结构的私有版本?
#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();
}
答案 0 :(得分:1)
如果没有重大的重构,您的程序将无法正常运行。如前所述,该程序展示了规范的数据竞争,多个线程同时更新共享数据结构而没有协调。
你可以:
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
。请注意使用reduction子句和默认可访问性声明为shared
。 OpenMP减少不能应用于结构元素或整个结构,这就是我抛弃zoo
的原因。
我不保证代码是正确的,但你应该明白这一点。