2015-10-08 1 views
3

J'essaie d'implémenter un simple tampon circulaire.Mon tampon circulaire simple ne fonctionne pas correctement

class MyCircularBuffer 
{ 
    byte[] Buffer = null; 

    private Object BufferLock = new object(); 

    int readIndex = 0; 
    int writeIndex = 0; 

    int SpaceBetweenIndexes 
    { 
     get; 
     set; 
    } 

    int ReadIndex 
    { 
     get 
     { 
      return readIndex; 
     } 
     set 
     { 
      readIndex = value; 
      CalculateSpaceBetweenIndexes(); 
     } 
    } 

    void CalculateSpaceBetweenIndexes() 
    { 
     if (readIndex <= writeIndex) 
     { 
      SpaceBetweenIndexes = writeIndex - readIndex; 
     } 
     else 
     { 
      SpaceBetweenIndexes = Length - (readIndex - writeIndex); 
     } 
    } 

    int WriteIndex 
    { 
     get 
     { 
      return writeIndex; 
     } 
     set 
     { 
      writeIndex = value; 
      CalculateSpaceBetweenIndexes(); 
     } 
    } 

    int Length; 

    int Count 
    { 
     get 
     { 
      lock(BufferLock) 
      { 
       return Buffer.Count(); 
      } 
     } 
    } 

    public MyCircularBuffer(int length) 
    { 
     Buffer = new byte[length]; 
     this.Length = length; 
     ReadIndex = 0; 
     WriteIndex = 0; 
    } 

    public byte ReadByte() 
    { 
     while (SpaceBetweenIndexes <= 1) 
     { 
      CalculateSpaceBetweenIndexes(); 
     } 

     ReadIndex++; 

     if (ReadIndex < Length) 
     { 
      Console.WriteLine("Read from index " + (ReadIndex-1) + " value " + this[ReadIndex - 1]); 
      return this[ReadIndex - 1]; 
     } 
     else 
     { 
      ReadIndex = 0; 
      Console.WriteLine("Read from index " + (Length-1) + " value " + this[Length-1]); 
      return this[Length-1]; 
     } 
    } 

    public void WriteByte(byte value) 
    { 
     WriteIndex++; 

     if (WriteIndex < Length) 
     { 
      Console.WriteLine("Wrote from index " + (WriteIndex-1) + " value " + value); 
      this[WriteIndex - 1] = value; 
     } 

     else if(writeIndex == Length) 
     { 
      Console.WriteLine("Wrote from index " + (WriteIndex-1) + " value " + value); 
      this[WriteIndex-1] = value; 

      WriteIndex = 0; 
     } 
    } 

    public byte this[int index] 
    { 
     get 
     { 
      lock(BufferLock) 
      { 
       return Buffer[index]; 
      } 
     } 
     set 
     { 
      lock(BufferLock) 
      { 
       Buffer[index] = value; 
      } 
     } 
    } 
} 

code pour générer le test:

class Program 
{ 


    public static MyCircularBuffer buff = new MyCircularBuffer(10); 

    static void Main(string[] args) 
    { 


     System.Threading.Thread t1 = new System.Threading.Thread(new System.Threading.ThreadStart(DrawByte)); 
     System.Threading.Thread t2 = new System.Threading.Thread(new System.Threading.ThreadStart(WriteByte)); 


     t2.Start(); 

     t1.Start(); 


     Console.ReadKey(); 
    } 

    public static void DrawByte() 
    { 
     Random rand = new Random(50); 

     for (int i = 0; i < 20; i++) 
     { 
      buff.WriteByte((byte)(rand.Next()+1)); 
     } 
    } 

    public static void WriteByte() 
    { 
     for (int i = 0; i < 20; i++) 
     { 
      buff.ReadByte(); //In this example my class is showing the results, so I didn't write here Console.Writeline... 
     } 
    } 
} 

fil d'abord utilisera la méthode ReadByte pour obtenir octets de ce tampon et le second fil utilisera la méthode WriteByte pour les octets d'écriture dans la mémoire tampon. J'ai writeindex et readindex qui se déplacent sur le buffer. Tout semble fonctionne bien, mais ceci:

a bug http://i62.tinypic.com/2d9tmrd.png

Toutes les idées/conseils? J'espère que vous pouvez m'aider, les gars!

+0

Vous devriez peut-être ajouter le code pour générer le cas de test, de sorte que les personnes répondant à la question puissent tester leur solution. –

+3

Vous devriez ajouter un verrouillage autour des méthodes 'readByte()' et 'writeByte()' – Domysee

+0

Que se passe-t-il lorsqu'un lecteur est à la traîne de l'auteur ou vice versa? Devraient-ils attendre les uns les autres? –

Répondre

-1

Je voudrais avoir assez de "réputation" pour mettre cela à commenter. Quoi qu'il en soit, pourquoi croiriez-vous qu'il y a un problème? Dans la boîte rouge que vous avez mise en surbrillance, le fil du lecteur n'attendait-il pas? Une fois qu'il a eu une chance de courir, il a choisi l'indice 8, qui était la bonne valeur.

+0

Est-ce le problème, parce que le lecteur a sauté un tour entier. Par exemple écrivain a écrit 1 2 3 4 5 6 7 8 9 10 11 dans le tampon avec la longueur 5, ainsi le lecteur a lu 1,2,3,4,5, 11 (ainsi sauté 6,7,8,9,10) – Terrykk

+2

Qu'est-ce qui fait que l'écrivain attend le lecteur? Writer peut continuer à écrire dans le tampon circulaire, lorsque le lecteur a une chance de l'exécuter, il récupère simplement la valeur de ReadIndex. Dans ce cas est 0, la valeur à l'index 0 est 11. Suis-je manquer quelque chose? –

+0

oh, c'est stupide mais je n'ai rien pour que l'écrivain attende le lecteur. Les conditions que j'ai écrites ne suffisent pas pour cela, merci. Je vais essayer de faire quelque chose avec ça – Terrykk