Plusieurs Producteurs de Multiples Consommateurs sans verrouillage (ou même attendre sans file d'attente

StackOverflow https://stackoverflow.com/questions/6078292

Question

Je suis à la recherche de la documentation sur la façon d'écrire de MP/MC file d'attente pour être sans verrouillage ou même attendre-gratuit.Je suis en utilisant .Net 4.0.Trouvé beaucoup de code C++, mais je ne suis pas très familier avec les modèles de mémoire, donc il y a une grande chance, je vais vous présenter quelques bugs lors de portage en C#.

Était-ce utile?

La solution

Pourquoi pensez-vous que vous avez besoin sans verrouillage de la file d'attente?Avez-vous essayé d'utiliser ConcurrentQueue<T>, éventuellement enfermé à l'intérieur d'un BlockingCollection<T>?

L'écriture du code multithread est dur.L'écriture de code sans verrouillage est encore plus difficile et vous ne devriez pas le faire vous-même sauf si vous devez vraiment.

Autres conseils

comme une option à considérer, il y a un algorithme de La file d'attente multiple multiple multiple multiple de producteurs par Dmitry Vyukov .J'ai porté l'algorithme à .net, vous pouvez trouver Les sources sur GitHub .C'est très vite.

L'algorithme Enqueuvé:

public bool TryEnqueue(object item)
{
    do
    {
        var buffer = _buffer; // prefetch the buffer pointer
        var pos = _enqueuePos; // fetch the current position where to enqueue the item
        var index = pos & _bufferMask; // precalculate the index in the buffer for that position
        var cell = buffer[index]; // fetch the cell by the index
        // If its sequence wasn't touched by other producers
        // and we can increment the enqueue position
        if (cell.Sequence == pos && Interlocked.CompareExchange(ref _enqueuePos, pos + 1, pos) == pos)
        {
            // write the item we want to enqueue
            Volatile.Write(ref buffer[index].Element, item);
            // bump the sequence
            buffer[index].Sequence = pos + 1;
            return true;
        }

        // If the queue is full we cannot enqueue and just return false
        if (cell.Sequence < pos)
        {
            return false;
        }

        // repeat the process if other producer managed to enqueue before us
    } while (true);
}

L'algorithme de Dequeue:

public bool TryDequeue(out object result)
{
    do
    {
        var buffer = _buffer; // prefetch the buffer pointer
        var bufferMask = _bufferMask; // prefetch the buffer mask
        var pos = _dequeuePos; // fetch the current position from where we can dequeue an item
        var index = pos & bufferMask; // precalculate the index in the buffer for that position
        var cell = buffer[index]; // fetch the cell by the index
        // If its sequence was changed by a producer and wasn't changed by other consumers
        // and we can increment the dequeue position
        if (cell.Sequence == pos + 1 && Interlocked.CompareExchange(ref _dequeuePos, pos + 1, pos) == pos)
        {
            // read the item
            result = Volatile.Read(ref cell.Element);
            // update for the next round of the buffer
            buffer[index] = new Cell(pos + bufferMask + 1, null);
            return true;
        }

        // If the queue is empty return false
        if (cell.Sequence < pos + 1)
        {
            result = default(object);
            return false;
        }

        // repeat the process if other consumer managed to dequeue before us
    } while (true);
}

Mon premier serait avec ConcurrentQueue<T> mais vous pouvez résumé de vos données entreposer à l'abri derrière une interface de sorte que vous pouvez facilement changer les implémentations.Puis de référence scénarios typiques et de voir où vous rencontrez des problèmes.Souvenez-vous:Prématuré optimzation est la racine de tous les maux.La conception de votre système de sorte qu'il n'est pas lié à une mise en œuvre, mais à un contrat et puis vous pouvez optimiser vos implémentations tout ce que vous voulez.

J'ai eu un coup d'oeil à ConcurrentQueue<T> avec ILSpy et semble être un lock gratuit de mise en œuvre, au premier abord, donc, bonne chance, c'est exactement ce que vous cherchez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top