2016-12-29 1 views
1

J'ai créé un pool de threads qui écrit sur le même vecteur en même temps.L'affectation à un élément std :: vector thread-safe?

Ce fil d'implémentation est-il sécuritaire?

Si ce n'est pas le cas, comment dois-je le réparer?

std::vector<double> global_var; 

void func1(int i) 
{ 
    global_var[i]=some_computation(i /* only depends on i */); 
} 

void load_distribution() 
{ 
    const int N_max=100; 
    global_var.assign(N_max,0.0); 
    std::vector<std::thread> th_pool; 
    for(long i=0;i<N_max;i++) 
     th_pool.push_back(std::thread(func1,i)); 

    for(std::thread& tp : th_pool) 
     tp.join(); 
} 

Mise à jour

global_var ne seront pas touchés par toute autre partie du programme avant que toutes les discussions terminées.

+1

Bien que je déteste admettre, l'extrait courant est réellement thread-safe. ... Pourtant, votre design est vraiment fragile. Il peut y avoir une autre partie de votre code qui peut modifier 'global_var' qui introduira un comportement indéterminé. – WhiZTiM

+0

@WhiZTiM Je garantis que' global_var' ne sera pas modifié par une autre partie du programme avant que tous les threads ne se terminent. – ar2015

+0

le code complet [ici] (http://pastebin.com/S3GYTYBf) pour juste au cas où. – ar2015

Répondre

1

En supposant que votre vecteur global ne soit modifié par aucune autre partie du code, votre code est thread-safe.

Chaque thread va écrire (accès) dans une cellule différente du vecteur, donc il n'y a pas de problème "dirty update".

De plus, le type du vecteur est un double, dans une architecture moderne est plus grande que la taille d'un mot. Ainsi, chaque cellule de tableau ne se chevauche pas entre d'autres.

+0

Merci beaucoup. Et si j'utilise un 'vecteur '. Peut-il faire n'importe quel problème? – ar2015

+0

@ ar2015 Pas si la mémoire est allouée de manière alignée –

+0

quelle est la manière alignée de l'allocation de mémoire ou quel est un exemple de façon non-alignée? – ar2015

-1

Généralement, std::vector n'est pas thread-safe, mais le code ci-dessus fonctionnera parce que la matrice de sauvegarde est préallouée avec la méthode assign().

Tant que les graveurs ne provoquent pas la réaffectation de la matrice de sauvegarde, le code fonctionnera. La méthode assign() permet de préallouer suffisamment d'espace pour que cela ne se produise pas lorsque le thread y écrit.

+0

Merci. Mais comment dois-je réparer ce code? – ar2015

+0

En fait, une affectation a déjà été utilisée 'global_var.assign (N_max, 0.0); ' – ar2015

+0

Et si au lieu de' vector ', j'utilise' vector 'qui contiendra d'autres vecteurs à l'intérieur d'eux-mêmes. Dans ce cas, l'affectation invalide-t-elle le vecteur? – ar2015

1

[container.requirements.dataraces]/1-2:

1 Aux fins d'éviter les courses de données ([res.on.data.races]), les mises en œuvre considèrent que les fonctions suivantes pour être const: begin, end, rbegin, rend , front, back, data, [...], at et, sauf dans des conteneurs associatifs associatifs ou non, operator[].

2 Nonobstant ([res.on.data.races]), les mises en œuvre sont nécessaires pour éviter des courses de données lorsque le contenu de l'objet contenu dans éléments différents dans le même récipient, à l'exception de vector<bool>, sont modifiés simultanément .