Quelles sont les solutions aux dangers de le faire?Fil de sécurité compteur en utilisant OpenMP
#include <iostream>
#include <unistd.h>
#include <cstdlib>
#include <ctime>
int main(){
int k = 0;
#pragma omp parallel for
for(int i = 0; i < 100000; i++){
if (i % 2){ /** Conditional based on i **/
#pragma omp atomic
k++;
usleep(1000 * ((float)std::rand()/RAND_MAX));
#pragma omp task
std::cout << k << std::endl; /** Some sort of task **/
}
}
return 0;
}
J'ai besoin que tous les k
s soient uniques. Quelle serait la meilleure façon de faire cela?
Modifier
Remarquez comment this question fait référence à un global
En particulier, je veux reproduire des tâches basées sur une variable partagée. Je cours le risque d'avoir une condition de course.
Considérons le thread 2 qui se termine, évalue true pour le conditionnel, et incrémente k avant que le thread 1 n'engendre toutes les tâches.
Éditer modifier
J'ai essayé de forcer une condition de concurrence. Ce n'était pas évident sans le sommeil. Il y a en fait des problèmes. Comment puis-je surmonter cela.
Voici une solution rapide:
...
#pragma omp atomic
k++;
int c = k;
...
mais je voudrais une garantie.
Tangentiel. Pourquoi cette implémentation ne fonctionne-t-elle pas?
...
int c;
#pragma omp crtical
{
k++;
c = k;
}
...
A la fin de la fonction, std::cout << k;
, est toujours inférieure à la sortie attendue 50000 proof
Possible dupliquer de [Comment gérer la variable partagée dans OpenMp] (http://stackoverflow.com/questions/14569954/how-to-manage-shared-variable -in-openmp) – Igor
@Igor Réponse mise à jour soulignant la différence –
La variante 'critical' devrait fonctionner de la même manière que dans 1)' k == 50000' à la fin de la boucle 'c == (i + 1)/2' . Vous devriez cependant 'std :: cout << c' pendant la boucle et lire' k' seulement dans la section critique en dehors de la boucle du parllel. – Zulan