Threads question

  • Thread starter Thread starter is_vlb50
  • Start date Start date
I

is_vlb50

I have general question,
It is exist one (Main) thread, which get some data(for exple simple
sting
packet).Exist big number of working threads(1000), which are waiting
for new data from Main thread.
How to organise application(prototype), that main thread will notify
to
all waiting threads that new data arrive and will not wait, that
working threads complete to read that data, that all working thread
will get immediately new data and not lose nothing?
Thanks
 
Well, a variety of thread sync features exist in the framework. You could
have all threads WaitForSingleObject and signal them when the data is
available, or you could iterate through each thread (assuming you've held a
reference to them all in some kind of global array) and call Interrupt on
them.

I think before you go any further though, you may want to reconsider exactly
why you feel you need so many threads. I would be concerned about stability
and resource usage at that sort of level. Why do you feel you need such a
huge number of threads?

HTH,
Alex
 
I have general question,
It is exist one (Main) thread, which get some data(for exple simple
sting
packet).Exist big number of working threads(1000), which are waiting
for new data from Main thread.
How to organise application(prototype), that main thread will notify
to
all waiting threads that new data arrive and will not  wait, that
working threads complete to read that data, that all working thread
will get immediately new data and not lose nothing?
Thanks

First, you should rethink your design regarding the large number of
threads. I cannot think of any reason whatsoever to have that many
threads...ever.

It sounds like your best option to communicate with the worker threads
is through a blocking queue. Basically, the worker threads will sit
idle in an infinite loop waiting for an object to appear in the
queue. Once the object is enqueued by the main thread the worker
thread will wake and dequeue for processing. After processing is
complete the worker thread will spin around to the beginning of the
loop again wait for the next object to appear.
 
First, you should rethink your design regarding the large number of
threads. I cannot think of any reason whatsoever to have that many
threads...ever.

It sounds like your best option to communicate with the worker threads
is through a blocking queue. Basically, the worker threads will sit
idle in an infinite loop waiting for an object to appear in the
queue. Once the object is enqueued by the main thread the worker
thread will wake and dequeue for processing. After processing is
complete the worker thread will spin around to the beginning of the
loop again wait for the next object to appear.

Here is a simple example of creating something like a waitable queue.
Basically, the consumer thread waits on the global queues waithandle. This
gets set everytime an object is added to the queue. A threading timer acts as
a procducer thread, firing at different intervals and inserting random
commands. This is a very simple implmentation (one i worked up in a few
minutes time for another thread on the msdn forums), and to be honest probably
would fall down with multiple producers/consumers - but, it is a place to
start for the OP.

Option Strict On
Option Explicit On

Imports System.Collections.ObjectModel
Imports System.Collections.Generic
Imports System.Threading

Module Module1
Private wq As New WaitableQueue(Of String)
Private pt As New Threading.Timer(AddressOf Producer, Nothing, 5000, 500)
Private e As Boolean
Private commands() As String = {"command 1", "command 2", "command 3", "command 4"}
Private rnd As New Random()

Sub Main()
Dim ct As New Thread(AddressOf Consumer)
ct.Start()
Console.ReadKey()
e = True

End Sub

Sub Producer(ByVal state As Object)
Dim command As String = commands(rnd.Next(0, commands.Length))
Console.WriteLine("enqueuing {0}", command)
wq.Enqueue(command)
pt.Change(rnd.Next(0, 1000), rnd.Next(0, 1000))
End Sub

Sub Consumer()
While Not e
wq.SetEvent.WaitOne()
Dim command As String = wq.Dequeue()
Console.WriteLine("executing {0}", command)
End While
End Sub

Class WaitableQueue(Of T)
Implements IEnumerable(Of T), ICollection, IDisposable

Private _sync As New Object
Private _queue As New Queue(Of T)
Private _wait As New AutoResetEvent(False)

Public Sub Enqueue(ByVal item As T)
SyncLock _sync
_queue.Enqueue(item)
_wait.Set()
End SyncLock
End Sub

Public Function Dequeue() As T
SyncLock _sync
Return _queue.Dequeue()
End SyncLock
End Function

Public ReadOnly Property SetEvent() As WaitHandle
Get
Return _wait
End Get
End Property
Public Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of T) Implements System.Collections.Generic.IEnumerable(Of T).GetEnumerator
Return DirectCast(_queue, IEnumerable(Of T)).GetEnumerator()
End Function

Public Function GetEnumerator1() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
Return DirectCast(_queue, IEnumerable).GetEnumerator()
End Function

Public Sub CopyTo(ByVal array As System.Array, ByVal index As Integer) Implements System.Collections.ICollection.CopyTo
DirectCast(_queue, ICollection).CopyTo(array, index)
End Sub

Public ReadOnly Property Count() As Integer Implements System.Collections.ICollection.Count
Get
Return _queue.Count
End Get
End Property

Public ReadOnly Property IsSynchronized() As Boolean Implements System.Collections.ICollection.IsSynchronized
Get
Return DirectCast(_queue, ICollection).IsSynchronized
End Get
End Property

Public ReadOnly Property SyncRoot() As Object Implements System.Collections.ICollection.SyncRoot
Get
Return DirectCast(_queue, ICollection).SyncRoot
End Get
End Property

Private disposedValue As Boolean = False ' To detect redundant calls

' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: free other state (managed objects).
_wait.Close()
End If

' TODO: free your own state (unmanaged objects).
' TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub

#Region " IDisposable Support "
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region

End Class
End Module
 
Back
Top