Ce qui suit est extrait de l'article de Herb Sutter sur les files d'attente concurrentes sans verrou. http://www.drdobbs.com/parallel/writing-a-generalized-concurrent-queue/211601363?pgno=1 . J'ai fait quelques changements comme la réorganisation du compilateur. Il faut GCC v4.4+ pour compiler ce code.
#include <atomic>
#include <iostream>
using namespace std;
//compile with g++ setting -std=c++0x
#define CACHE_LINE_SIZE 64
template <typename T>
struct LowLockQueue {
private:
struct Node {
Node( T* val ) : value(val), next(nullptr) { }
T* value;
atomic<Node*> next;
char pad[CACHE_LINE_SIZE - sizeof(T*)- sizeof(atomic<Node*>)];
};
char pad0[CACHE_LINE_SIZE];
// for one consumer at a time
Node* first;
char pad1[CACHE_LINE_SIZE
- sizeof(Node*)];
// shared among consumers
atomic<bool> consumerLock;
char pad2[CACHE_LINE_SIZE
- sizeof(atomic<bool>)];
// for one producer at a time
Node* last;
char pad3[CACHE_LINE_SIZE
- sizeof(Node*)];
// shared among producers
atomic<bool> producerLock;
char pad4[CACHE_LINE_SIZE
- sizeof(atomic<bool>)];
public:
LowLockQueue() {
first = last = new Node( nullptr );
producerLock = consumerLock = false;
}
~LowLockQueue() {
while( first != nullptr ) { // release the list
Node* tmp = first;
first = tmp->next;
delete tmp->value; // no-op if null
delete tmp;
}
}
void Produce( const T& t ) {
Node* tmp = new Node( new T(t) );
asm volatile("" ::: "memory"); // prevent compiler reordering
while( producerLock.exchange(true) )
{ } // acquire exclusivity
last->next = tmp; // publish to consumers
last = tmp; // swing last forward
producerLock = false; // release exclusivity
}
bool Consume( T& result ) {
while( consumerLock.exchange(true) )
{ } // acquire exclusivity
Node* theFirst = first;
Node* theNext = first-> next;
if( theNext != nullptr ) { // if queue is nonempty
T* val = theNext->value; // take it out
asm volatile("" ::: "memory"); // prevent compiler reordering
theNext->value = nullptr; // of the Node
first = theNext; // swing first forward
consumerLock = false; // release exclusivity
result = *val; // now copy it back
delete val; // clean up the value
delete theFirst; // and the old dummy
return true; // and report success
}
consumerLock = false; // release exclusivity
return false; // report queue was empty
}
};
int main(int argc, char* argv[])
{
//Instead of this Mambo Jambo one can use pthreads in Linux to test comprehensively
LowLockQueue<int> Q;
Q.Produce(2);
Q.Produce(6);
int a;
Q.Consume(a);
cout<< a << endl;
Q.Consume(a);
cout<< a << endl;
return 0;
}
4 votes
Visual Studio 2010 contient une file d'attente sans verrou dans <concurrent_queue.h>.
1 votes
Et il y a un hash_map et un unordered_map à code.msdn.com/concrtextras
0 votes
J'ai lu la documentation sur concurrent_queue.h à l'adresse http://msdn.microsoft.com/en-us/library/ee355358.aspx. Elle ne dit rien sur les verrous. Où puis-je trouver de telles informations ?
0 votes
Concurrent_queue est sans verrou, consultez la documentation générale de l'exécution concurrentielle sur msdn.
2 votes
Il est à noter que, curieusement, le terme "lock-free" ne signifie pas nécessairement qu'il n'y a pas de verrous. Voir fr.wikipedia.org/wiki/Non-blocking_algorithm pour une définition.
0 votes
Boost 1.53 dispose de la bibliothèque Lockfree.
0 votes
Quelqu'un a-t-il mentionné libcds.sourceforge.net (assez récent je suppose) ? De plus, on remarque qu'il n'est pas logique qu'une file d'attente lockfree soit conforme à l'API STL parce que front() et pop() doivent être combinés pour être significatifs.
13 votes
Wow, une question demandant comment résoudre un problème commun mais difficile dans la programmation multithread qui a plusieurs solutions, a généré beaucoup de discussions, et a gagné une tonne d'upvotes... Et 9 ans plus tard, vous la fermez parce qu'elle est hors sujet. Merci pour votre contribution à StackOverflow, NathanOliver, Sir E_net4 the Wise Downvoter, Jean-François Fabre, Machavity, et gre_gor /s
0 votes
Est-ce que quelqu'un parmi les "fermiers" peut donner un indice sur ce qui devrait être considéré comme "hors sujet" ? De mon point de vue, ce problème n'est toujours pas résolu de manière généralisée, réutilisable et multiplateforme ? Comment allez-vous clore cette question ? Ou est-ce que stackoverflow est maintenant un forum réservé aux débutants ?
2 votes
Je dirais que les personnes qui ont fermé la question ne la comprennent probablement pas.
0 votes
"Nous n'autorisons pas les questions portant sur des recommandations de livres, d'outils, de bibliothèques de logiciels, etc. J'ai trouvé un certain nombre d'outils très utiles ici !