Results 1 to 7 of 7

Thread: [RESOLVED] Random Bug

Threaded View

  1. #1

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Resolved [RESOLVED] Random Bug

    This weekend I watched a video on YouTube(see comments for link) that said there is a bug in the Random class when used with threading. It was in C# so I thought I'd recreate it in VB. I was surprised to find it does fail. And after failing the first time it is like the Random is broken.

    To use this code create a Form with three buttons and two labels with default names.

    Button 1 is a sanity check and only fails after Button 2 fails.

    Code:
        ' Is this  https://www.youtube.com/watch?v=WRB4OHpSXHs
        '   true?
        ' .Net 4.8
        '
        ' Strictly speaking zero values aren't errors.
        '  Documentation says this about .Next 
        '   A 32-bit signed integer that is greater than or equal to 0 and less than Int32.MaxValue.
        ' but ...
    
        Private Shared PRNG As New Random
        Private LRand As Concurrent.BlockingCollection(Of Integer)
        Const Tries As Integer = 100000
        Const Thrds As Integer = 25
        Private STPW As New Stopwatch
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            SetUp()
    
            For x As Integer = 1 To Tries * Thrds
                LRand.Add(PRNG.Next)
            Next
            STPW.Stop()
            Dim Nzro As Integer
            Nzro = (From i In LRand Where i > 0 Select i).Count
            Dim zct As Integer = LRand.Count
            If Nzro <> zct Then
                Label1.Text = "1 ERR  " & (Nzro / zct).ToString("p1") 'per cent of non-zero values
            Else
                Label1.Text = "Good  " & Nzro.ToString("n0")
            End If
            Label2.Text = STPW.Elapsed.TotalMilliseconds.ToString("n1")
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            SetUp()
    
            Parallel.For(1, Thrds + 1,
                         Sub(idx As Integer)
                             For zx As Integer = 1 To Tries
                                 Do While Not LRand.TryAdd(PRNG.Next)
                                     Threading.Thread.Sleep(0)
                                 Loop
                             Next
                         End Sub)
            STPW.Stop()
            Dim Nzro As Integer
            Nzro = (From i In LRand Where i > 0 Select i).Count
            Dim zct As Integer = LRand.Count
            If Nzro <> zct Then
                Label1.Text = "2 ERR  " & (Nzro / zct).ToString("p1") 'per cent of non-zero values
            Else
                Label1.Text = "Good  " & Nzro.ToString("n0")
            End If
            Label2.Text = STPW.Elapsed.TotalMilliseconds.ToString("n1")
        End Sub
    
        Private Sub SetUp()
            ' PRNG = New Random
            Label1.Text = ""
            LRand = New Concurrent.BlockingCollection(Of Integer)
            STPW.Restart()
        End Sub
    Here is what I did to fix? this issue,

    Code:
        Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
            SetUp()
    
            Parallel.For(1, Thrds + 1,
                         Sub(idx As Integer)
                             For zx As Integer = 1 To Tries
                                 Do While Not LRand.TryAdd(MyPRNG.NextI)
                                     Threading.Thread.Sleep(0)
                                 Loop
                             Next
                         End Sub)
            STPW.Stop()
            Dim Nzro As Integer
            Nzro = (From i In LRand Where i > 0 Select i).Count
            Dim zct As Integer = LRand.Count
            If Nzro <> zct Then
                Label1.Text = "3 ERR  " & (Nzro / zct).ToString("p1") 'per cent of non-zero values
            Else
                Label1.Text = "Good  " & Nzro.ToString("n0")
            End If
            Label2.Text = STPW.Elapsed.TotalMilliseconds.ToString("n1")
        End Sub
    
        Private Class MyPRNG
            Private Shared Block As New Threading.SpinLock '(True)
            Private Shared _PRNG As New Random
    
            Public Shared Sub NextB(buffer() As Byte)
                Block.Enter(Nothing)
                _PRNG.NextBytes(buffer)
                If Block.IsHeld Then
                    Block.Exit()
                End If
            End Sub
    
            Public Shared Function NextD() As Double
                Block.Enter(Nothing)
                NextD = _PRNG.NextDouble
                If Block.IsHeld Then
                    Block.Exit()
                End If
            End Function
    
            Public Shared Function NextI() As Integer
                Block.Enter(Nothing)
                NextI = _PRNG.Next
                If Block.IsHeld Then
                    Block.Exit()
                End If
            End Function
    
            Public Shared Function NextI(maxValXclu As Integer) As Integer
                Block.Enter(Nothing)
                NextI = _PRNG.Next(maxValXclu)
                If Block.IsHeld Then
                    Block.Exit()
                End If
            End Function
    
            Public Shared Function NextI(minValIlu As Integer, maxValXclu As Integer) As Integer
                Block.Enter(Nothing)
                NextI = _PRNG.Next(minValIlu, maxValXclu)
                If Block.IsHeld Then
                    Block.Exit()
                End If
            End Function
        End Class
    Last edited by dbasnett; Oct 11th, 2022 at 01:38 PM.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width