Многопоточный геттер System.IndexOutOfRangeException - C#
Формулировка задачи:
Есть такой код, так вот не могу понять почему в переменную next, которая используется как счетчик проскакивает число больше массива байтов, когда по идее запрос значения next должен пройти через геттер функцию и там в данном случае попасть в цикл, пока значение next не станет меньше размера массива байтов, но периодически 2 - 3 параллельно работающих потока с первым потоком (поток, который запускает поток Seed(0) и переходит в ожидание завершения запущенного потока) не останавливаясь в геттере забирают значение переменной next больше размера массива.
Листинг программы
- public static class Random
- {
- // 4 Mb Random bytes buffer
- private static byte[] seedArr = new byte[4194304];
- private static Thread waiter;
- private static long _next;
- private static long next
- {
- get
- {
- if (_next >= seedArr.LongLength && waiter == null)
- {
- waiter = new Thread(() => Seed(0));
- waiter.Start();
- waiter.Join();
- waiter = null;
- _next = 0;
- }
- while (_next >= seedArr.LongLength)
- {
- if (waiter != null && waiter.ThreadState == ThreadState.Running)
- {
- waiter.Join();
- }
- Thread.SpinWait(1);
- }
- return _next;
- }
- set
- {
- _next = value;
- }
- }
- public static void Seed(ulong Seed)
- {
- if (Seed.GetType() != typeof(ulong) || Seed <= 0)
- {
- RNGCryptoServiceProvider CSP = new RNGCryptoServiceProvider();
- byte[] bytes = new byte[8];
- CSP.GetNonZeroBytes(bytes);
- CSP.Dispose();
- Seed = BitConverter.ToUInt64(bytes, 0);
- }
- {
- ulong[] ticks = new ulong[4] {
- ulong.MaxValue,
- Convert.ToUInt64(DateTime.UtcNow.Ticks),
- Convert.ToUInt64(Environment.TickCount),
- Convert.ToUInt64(Thread.CurrentThread.ManagedThreadId)
- };
- ulong[] modules_a = new ulong[4] {
- ticks[0] / ticks[1],
- ticks[0] % ticks[1],
- ticks[0] / ticks[2],
- ticks[0] % ticks[2]
- };
- byte[] bytes = new byte[8];
- {
- byte[] bytes_t = new byte[524288];
- {
- byte[] sbytes = BitConverter.GetBytes(Seed);
- MemoryStream bytebuff = new MemoryStream();
- bytebuff.Write(sbytes, 0, sbytes.Length);
- Extensions.ParallelFor(1, 4, i =>
- {
- byte[] tbytes = BitConverter.GetBytes(ticks[i]);
- lock (bytebuff)
- {
- bytebuff.Write(tbytes, 0, tbytes.Length);
- }
- });
- Extensions.ParallelFor(0, 4, i =>
- {
- byte[] mbytes = BitConverter.GetBytes(modules_a[i]);
- lock (bytebuff)
- {
- bytebuff.Write(mbytes, 0 , mbytes.Length);
- }
- });
- byte[] seedb = bytebuff.ToArray();
- bytebuff.Dispose();
- {
- byte[] rseedb = seedb;
- rseedb.Reverse();
- int sl = seedb.Length, rsl = rseedb.Length;
- MemoryStream buff = new MemoryStream();
- buff.Write(seedb, 0, sl);
- buff.Write(rseedb, 0, rsl);
- for (int i = 0; i < 2; i++)
- {
- rseedb = buff.ToArray();
- buff.Write(rseedb, 0, rseedb.Length);
- }
- seedb = buff.ToArray();
- buff.Dispose();
- }
- RNGCryptoServiceProvider CSP = new RNGCryptoServiceProvider();
- HMACMD5 hmacmd5 = new HMACMD5(seedb);
- HMACSHA512 hmacsha512 = new HMACSHA512(seedb);
- CSP.GetNonZeroBytes(bytes_t);
- byte[] md5 = hmacmd5.ComputeHash(bytes_t, 0, bytes_t.Length), sha512 = hmacsha512.ComputeHash(bytes_t, 0, bytes_t.Length);
- CSP.Dispose();
- hmacmd5.Dispose();
- hmacsha512.Dispose();
- long md5l = md5.LongLength, sha512l = sha512.LongLength;
- // for (int i = 0, l = bytes_t.Length, pos = 0; i < l; i++)
- Extensions.ParallelFor(0, bytes_t.LongLength, i =>
- {
- long posmd5 = i % md5l, possha512 = i % sha512l;
- bytes_t[i] ^= md5[posmd5];
- bytes_t[i] ^= sha512[possha512];
- });
- md5 = null;
- sha512 = null;
- }
- Extensions.ParallelFor(0, bytes_t.LongLength, i =>
- {
- long pos = i % 8;
- lock (bytes)
- {
- bytes[pos] ^= bytes_t[i];
- }
- });
- bytes_t = null;
- }
- ulong modules = Convert.ToUInt64(Seed) ^ BitConverter.ToUInt64(bytes, 0), modules_x = 0, modules_t = 0, modules_xt = 0;
- modules_x = modules_a[0] ^ modules_a[1] ^ modules_a[2] ^ modules_a[3];
- modules_t = modules_x >> 1;
- modules_t = modules_x % modules_t;
- modules_t = modules_x ^ modules_t;
- ticks[1] ^= ticks[3];
- modules_xt = ticks[1] % modules_t;
- modules = modules ^ modules_t ^ modules_xt;
- Seed = modules;
- }
- {
- RNGCryptoServiceProvider CSP = new RNGCryptoServiceProvider();
- CSP.GetNonZeroBytes(seedArr);
- CSP.Dispose();
- byte[] bytes = BitConverter.GetBytes(Seed);
- Extensions.ParallelFor(0, seedArr.LongLength, i =>
- {
- long pos = i % 8;
- lock (seedArr)
- {
- seedArr[i] ^= bytes[pos];
- }
- });
- }
- Seed = 0;
- }
- private static byte GetByte()
- {
- byte retbyte;
- retbyte = seedArr[next]; // Здесь System.IndexOutOfRangeException
- next++;
- return retbyte;
- }
- public static byte[] NextBytes(ulong count = 1)
- {
- byte[] bytes = new byte[count];
- // for (int i = 0; i < count; i++)
- Extensions.ParallelFor(0, bytes.LongLength, i =>
- {
- byte lbyte = GetByte();
- bytes[i] = lbyte;
- });
- return bytes;
- }
- }
Решение задачи: «Многопоточный геттер System.IndexOutOfRangeException»
textual
Листинг программы
- Timer frequency as ticks per microsecond: 2343835000000
- Timer is high-resolution: True
- Max parallel threads pass: 4
- Serial 1Mb byte array, microseconds: 1375
- Parallel 1Mb byte array, microseconds: 3253
- Serial 2Mb byte array, microseconds: 2799
- Parallel 2Mb byte array, microseconds: 7084
- Serial 10Mb byte array, microseconds: 14196
- Parallel 10Mb byte array, microseconds: 33382
- Serial 18Mb byte array, microseconds: 25609
- Parallel 18Mb byte array, microseconds: 61043
- Serial 26Mb byte array, microseconds: 36987
- Parallel 26Mb byte array, microseconds: 85168
- Serial 34Mb byte array, microseconds: 48284
- Parallel 34Mb byte array, microseconds: 113083
- Serial 42Mb byte array, microseconds: 59928
- Parallel 42Mb byte array, microseconds: 140026
- Serial 50Mb byte array, microseconds: 71676
- Parallel 50Mb byte array, microseconds: 166940
- Serial 58Mb byte array, microseconds: 84363
- Parallel 58Mb byte array, microseconds: 194119
- Serial 66Mb byte array, microseconds: 94159
- Parallel 66Mb byte array, microseconds: 220923
- Serial 74Mb byte array, microseconds: 105542
- Parallel 74Mb byte array, microseconds: 244599
- Serial 82Mb byte array, microseconds: 116878
- Parallel 82Mb byte array, microseconds: 277487
- Serial 90Mb byte array, microseconds: 128088
- Parallel 90Mb byte array, microseconds: 297518
- Serial 98Mb byte array, microseconds: 139974
- Parallel 98Mb byte array, microseconds: 330158
- Serial 106Mb byte array, microseconds: 151253
- Parallel 106Mb byte array, microseconds: 356841
- Serial 114Mb byte array, microseconds: 161735
- Parallel 114Mb byte array, microseconds: 396256
- Serial 122Mb byte array, microseconds: 173373
- Parallel 122Mb byte array, microseconds: 413497
- Serial 130Mb byte array, microseconds: 185386
- Parallel 130Mb byte array, microseconds: 439991
- Serial 138Mb byte array, microseconds: 197546
- Parallel 138Mb byte array, microseconds: 464581
- Serial 146Mb byte array, microseconds: 209185
- Parallel 146Mb byte array, microseconds: 501030
- Serial 154Mb byte array, microseconds: 220108
- Parallel 154Mb byte array, microseconds: 535607
- Serial 162Mb byte array, microseconds: 232093
- Parallel 162Mb byte array, microseconds: 559694
- Serial 170Mb byte array, microseconds: 242831
- Parallel 170Mb byte array, microseconds: 592954
- Serial 178Mb byte array, microseconds: 255106
- Parallel 178Mb byte array, microseconds: 630598
- Serial 186Mb byte array, microseconds: 272178
- Parallel 186Mb byte array, microseconds: 797705
- Serial 194Mb byte array, microseconds: 275468
- Parallel 194Mb byte array, microseconds: 782837
- Serial 202Mb byte array, microseconds: 286021
- Parallel 202Mb byte array, microseconds: 829967
- Serial 210Mb byte array, microseconds: 298365
- Parallel 210Mb byte array, microseconds: 823702
- Serial 218Mb byte array, microseconds: 311791
- Parallel 218Mb byte array, microseconds: 753300
- Serial 226Mb byte array, microseconds: 327196
- Parallel 226Mb byte array, microseconds: 786166
- Serial 234Mb byte array, microseconds: 333410
- Parallel 234Mb byte array, microseconds: 809886
- Serial 242Mb byte array, microseconds: 352284
- Parallel 242Mb byte array, microseconds: 845802
- Serial 250Mb byte array, microseconds: 358615
- Parallel 250Mb byte array, microseconds: 897478
- Serial 258Mb byte array, microseconds: 373060
- Parallel 258Mb byte array, microseconds: 894993
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д