-
Jan 16th, 2015, 07:20 AM
#1
Thread Starter
Lively Member
Help Needed with a basic threading Problem
Hi all
I am just trying multi-threading for the first time and would appreciate some help.
I have written a small console app with a class that reads strings and counts occurrences of words which is a simple app just to try out Multi threading.
The app works perfectly and when I run the class in two threads it is still working well.
It writes each word to the console and so that I could indicate which word was produced by which Thread I gave the class a color property which it uses to print to the console.
Most of the time it works well but sometimes the words do not come out in the right colour.
I assume that, as the console is shared between threads, if one thread interrupted the other between setting the forecolour and writing the word then the word will get written in the wrong colour.
So I added Synclock Code
the code is
Dim lockThis As New Object
SyncLock lockThis
'Lock so that colour does not change '''' This does not work ! I probably do not understand Synclock!
Console.ForegroundColor = PropertyForecolour
Console.WriteLine(MyWord.Word & "=" & MyWord.count)
End SyncLock
Why doesn't this Work?
What else could I try?
advice most appreciated
Mike
-
Jan 16th, 2015, 08:17 AM
#2
Re: Help Needed with a basic threading Problem
While I know nothing about the console, are you locking everything on the same object?
"Ok, my response to that is pending a Google search" - Bucky Katt.
"There are two types of people in the world: Those who can extrapolate from incomplete data sets." - Unk.
"Before you can 'think outside the box' you need to understand where the box is."
-
Jan 16th, 2015, 10:20 AM
#3
Re: Help Needed with a basic threading Problem
Accidently duplicated post, so "deleting" this one.
Last edited by passel; Jan 16th, 2015 at 05:05 PM.
-
Jan 16th, 2015, 10:25 AM
#4
Re: Help Needed with a basic threading Problem
Yes, we can't tell by that snippet of code, but it looks like you might be declaring lockThis with a local scope.
It has to be accessible to both (or more) threads, so when one thread locks it, the others have to wait until is is released.
You could make it Static in a sub, and have both threads call that sub, passing the color and MyWord structure to the sub.
The SyncLock would prevent simultaneous access to the Console manipulation lines.
Code:
Private Sub WriteToConsole( c as ConsoleColor, w as WordStructure) ' or WordClass, or whatever MyWord is
Static lockThis As New Object
SyncLock lockThis
Console.ForegroundColor = c
Console.WriteLine(w.Word & "=" & w.count)
End SyncLock
End Sub
I'll actually have to test that as I don't usually declare an object both Static and New in a sub. Have to verify it only creates the object once and reuses it for every subsequent call.
p.s. A quick test seems to indicate it works fine. The hashcode for the object stays the same for every call, so I believe that indicates it is only created once. If you start doing a "Mark" edit selection, the console stops updating so can confirm that thread1 is always cyan and thread2 is always red.
If you comment out the synclock and end synclock, the colors are wrong quite often so synclock is doing what it is suppose to do.
My quick test code
Code:
Module Module1
Dim Thread1 As New Threading.Thread(AddressOf back1)
Dim Thread2 As New Threading.Thread(AddressOf back2)
Structure WordStructure
Public Word As String
Public Count As Integer
End Structure
Sub Main()
Thread1.IsBackground = True
Thread2.IsBackground = True
Thread1.Start()
Thread2.Start()
Dim s As String = Console.ReadLine
End Sub
Private Sub back1()
Dim myWord As WordStructure
myWord.Word = "Thread1 is here"
For i As Integer = 1 To 100000
myWord.Count = i
WriteToConsole(ConsoleColor.Cyan, myWord)
Next
End Sub
Private Sub back2()
Dim myWord As WordStructure
myWord.Word = "Thread2 is here"
For i As Integer = 1 To 100000
myWord.Count = i
WriteToConsole(ConsoleColor.Red, myWord)
Next
End Sub
Private Sub WriteToConsole(c As ConsoleColor, w As WordStructure) ' or WordClass, or whatever MyWord is
Static lockThis As New Object
SyncLock lockThis
Console.ForegroundColor = c
Console.WriteLine(w.Word & "=" & w.Count & " " & lockThis.GetHashCode.ToString)
End SyncLock
End Sub
End Module
Last edited by passel; Jan 16th, 2015 at 11:02 AM.
-
Jan 16th, 2015, 02:40 PM
#5
Re: Help Needed with a basic threading Problem
This counts words based on starting letter and shows the counts with a random color. Runs fine with the synclock, and the error is reproduced if the synclock is removed or the lock object scope is moved inside the sub.
Code:
Module Module1
Dim theLetters As String = "abcdefghijklmnopqrstuvwxyz"
Dim thrds As New List(Of Threading.Thread)
Dim someColors As New List(Of ConsoleColor) From {ConsoleColor.White, ConsoleColor.Green, ConsoleColor.Red, ConsoleColor.Yellow}
Dim prng As New Random
Sub Main()
Dim ki As ConsoleKeyInfo
Do
thrds.Clear()
Console.Clear()
For Each ch As Char In theLetters
Dim thrd As New Threading.Thread(AddressOf countAndShow)
thrd.IsBackground = True
thrds.Add(thrd)
thrd.Start(ch)
Next
Debug.WriteLine("")
Dim running As Integer = 0
Do
Debug.WriteLine(running)
If running <> 0 Then Threading.Thread.Sleep(10)
running = 0
For Each t As Threading.Thread In thrds
If t.IsAlive Then running += 1
Next
Loop While running > 0
Console.WriteLine("Press C to run again")
ki = Console.ReadKey(True)
Loop While ki.Key = ConsoleKey.C
End Sub
Dim tlock As New Object
Private Sub countAndShow(ch As Object)
Dim theCh As Char = DirectCast(ch, Char)
Dim ct As Integer = 0
For Each w As String In ipsumA
Dim wl As String = w.ToLowerInvariant
If wl.StartsWith(theCh) Then ct += 1
Next
If ct > 0 Then
Dim c As ConsoleColor = someColors(prng.Next(someColors.Count))
SyncLock tlock
Console.ForegroundColor = c
Console.WriteLine("There are {0} words that start with {1} . Color = {2}", ct, theCh, c.ToString)
End SyncLock
End If
End Sub
Dim ipsumA() As String = New String() {"Lorem", "ipsum", "dolor", "sit", _
"amet", "consectetur", "adipisicing", _
"elit", "sed", "do", "eiusmod", _
"tempor", "incididunt", "ut", "labore", _
"et", "dolore", "magna", "aliqua", "Ut", _
"enim", "ad", "minim", "veniam", "quis", _
"nostrud", "exercitation", "ullamco", _
"laboris", "nisi", "ut", "aliquip", "ex", _
"ea", "commodo", "consequat", "Duis", "aute", _
"irure", "dolor", "in", "reprehenderit", "in", _
"voluptate", "velit", "esse", "cillum", "dolore", _
"eu", "fugiat", "nulla", "pariatur", "Excepteur", _
"sint", "occaecat", "cupidatat", "non", "proident", _
"sunt", "in", "culpa", "qui", "officia", "deserunt", _
"amet", "consectetur", "adipisicing", _
"elit", "sed", "do", "eiusmod", _
"tempor", "incididunt", "ut", "labore", _
"et", "dolore", "magna", "aliqua", "Ut", _
"enim", "ad", "minim", "veniam", "quis", _
"nostrud", "exercitation", "ullamco", _
"laboris", "nisi", "ut", "aliquip", "ex", _
"ea", "commodo", "consequat", "Duis", "aute", _
"irure", "dolor", "in", "reprehenderit", "in", _
"voluptate", "velit", "esse", "cillum", "dolore", _
"eu", "fugiat", "nulla", "pariatur", "Excepteur", _
"sint", "occaecat", "cupidatat", "non", "proident", _
"sunt", "in", "culpa", "qui", "officia", "deserunt", _
"amet", "consectetur", "adipisicing", _
"elit", "sed", "do", "eiusmod", _
"tempor", "incididunt", "ut", "labore", _
"et", "dolore", "magna", "aliqua", "Ut", _
"enim", "ad", "minim", "veniam", "quis", _
"nostrud", "exercitation", "ullamco", _
"laboris", "nisi", "ut", "aliquip", "ex", _
"ea", "commodo", "consequat", "Duis", "aute", _
"irure", "dolor", "in", "reprehenderit", "in", _
"voluptate", "velit", "esse", "cillum", "dolore", _
"eu", "fugiat", "nulla", "pariatur", "Excepteur", _
"sint", "occaecat", "cupidatat", "non", "proident", _
"sunt", "in", "culpa", "qui", "officia", "deserunt", _
"mollit", "anim", "id", "est", "laborum"}
End Module
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|