Home All Groups Group Topic Archive Search About

How to create multiple threads?

Author
26 Jul 2006 1:11 PM
BogusException
I'll ask a simple question:

How can someone generate any number of threads from within a simple
"for" ot Timer loop/sub (including indefinitely)?

Dim i As Integer
For i = 1 To 10
        Dim t As New Thread(AddressOf DoSomethingSub)
        t.IsBackground = True
        t.Start()
Next i

Semi-surprisingly, the above code generates only 1 thread, not 10. Now
imagine that 100 are needed-or an indefinite amount! This approach
simply doesn't work. In reality, the number of threads needed is
arbitrary, so you can't just have a ton of pre-written Dim
statements...

So now imagine that you need to create and abort/join threads in an
ongoing fashion. An example is doing the above in a Timer's Tick
handler. The threads obviously need to be aborted/joined when the
repetative task is done to free up resources or the system will simply
run out of memory in short order.

Sounds [deceptively] easy, doesn't it! :)

TIA!

BogusException

Author
26 Jul 2006 1:35 PM
Patrice
How do you know it creates only a single thread ? IMO you mean  rather that
you keep only the reference to the last created thread ? (in which case you
could use an array).

--
Patrice

"BogusException" <bogusexcept***@gmail.com> a écrit dans le message de news:
1153919480.529377.47***@s13g2000cwa.googlegroups.com...
Show quoteHide quote
> I'll ask a simple question:
>
> How can someone generate any number of threads from within a simple
> "for" ot Timer loop/sub (including indefinitely)?
>
> Dim i As Integer
> For i = 1 To 10
>        Dim t As New Thread(AddressOf DoSomethingSub)
>        t.IsBackground = True
>        t.Start()
> Next i
>
> Semi-surprisingly, the above code generates only 1 thread, not 10. Now
> imagine that 100 are needed-or an indefinite amount! This approach
> simply doesn't work. In reality, the number of threads needed is
> arbitrary, so you can't just have a ton of pre-written Dim
> statements...
>
> So now imagine that you need to create and abort/join threads in an
> ongoing fashion. An example is doing the above in a Timer's Tick
> handler. The threads obviously need to be aborted/joined when the
> repetative task is done to free up resources or the system will simply
> run out of memory in short order.
>
> Sounds [deceptively] easy, doesn't it! :)
>
> TIA!
>
> BogusException
>
Author
26 Jul 2006 1:57 PM
BogusException
Patrice wrote:

> How do you know it creates only a single thread ? IMO you mean  rather that
> you keep only the reference to the last created thread ? (in which case you
> could use an array).

Patrice, Thanks for writing! I think you are right, but the symptom
remains: only one thread is available to the program at a time. Your
comment about arrays is rgeat, except that a continuously firing thread
generator would eventually use up the memory of the computer as the
size of the array grew!

TIA!

BogusException
Author
26 Jul 2006 2:20 PM
tomb
Actually, the memory would be depleted only if the threads never stopped
running.  As each thread does its thing, it ends and goes away - it is
deleted.  How long do these threads actually run?

T

BogusException wrote:

Show quoteHide quote
>Patrice wrote:
>

>
>>How do you know it creates only a single thread ? IMO you mean  rather that
>>you keep only the reference to the last created thread ? (in which case you
>>could use an array).
>>   
>>
>
>Patrice, Thanks for writing! I think you are right, but the symptom
>remains: only one thread is available to the program at a time. Your
>comment about arrays is rgeat, except that a continuously firing thread
>generator would eventually use up the memory of the computer as the
>size of the array grew!
>
>TIA!
>
>BogusException
>

>
Author
26 Jul 2006 2:56 PM
Patrice
Why would you want to continuously create new threads ? Also I'm not sure
what you meant by having a single thread "available" to the program (they
all run, if you keep a reference to each thread you can later test the state
of any thread you created or whatever else you want).

IMO your best bet would be to start by describing what you are trying to
do. It looks like you have a more general problem with threads.

Are you after a thread pool mechanism such as System.Threading.ThreadPool ?

--
Patrice

"BogusException" <bogusexcept***@gmail.com> a écrit dans le message de news:
1153922235.199952.304***@s13g2000cwa.googlegroups.com...
Show quoteHide quote
> Patrice wrote:
>
>> How do you know it creates only a single thread ? IMO you mean  rather
>> that
>> you keep only the reference to the last created thread ? (in which case
>> you
>> could use an array).
>
> Patrice, Thanks for writing! I think you are right, but the symptom
> remains: only one thread is available to the program at a time. Your
> comment about arrays is rgeat, except that a continuously firing thread
> generator would eventually use up the memory of the computer as the
> size of the array grew!
>
> TIA!
>
> BogusException
>
Author
26 Jul 2006 6:12 PM
BogusException
Patrice & tomb,

Thanks for writing!

The objective was to generate web traffic (load) for grid testing. And
the most efficient way I found was this:

Public Class Request

    Public Shared iRequestsTotal As Integer ' how many simultaneous
requests
    Public Shared iSentTotal As Integer ' how many sent total
    Public Shared iRecvdTotal As Integer ' total received
    Public Shared iTimedOutTotal As Integer ' total that timed out
    Public Shared iConcurrentRequests As Integer ' how many concurrent
requests right now?

    Public Sub DoRequest(ByVal sURL As String)
        'Dim URL As String = sURL
        Try
            Dim request As WebRequest = WebRequest.Create(sURL)
            iSentTotal = iSentTotal + 1
            iConcurrentRequests += 1
            Dim response As WebResponse = request.GetResponse()
            iRecvdTotal += 1
            response.Close()
            iConcurrentRequests -= 1
        Catch ex As System.Net.WebException
            iTimedOutTotal += 1
        Catch ex As UriFormatException
            MsgBox(" Invalid URL:" & sURL.ToString & vbCrLf &
ex.ToString, MsgBoxStyle.Critical)
        Catch ex As Exception
            MsgBox("Generic Exception:" & vbCrLf & ex.ToString,
MsgBoxStyle.Critical)
        Finally
            iRequestsTotal += 1
        End Try
    End Sub

End Class

This class then called via:

    Sub DoURL()
        Try
            Dim r As New Request
            r.DoRequest(txtURL.Text)
        Catch ex As Exception
            MsgBox("DoURL exception: " & ex.ToString)
        End Try
    End Sub

Which could be called either manually, or via a timer's tick:

    Private Sub tmrRequests_Tick(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles tmrRequests.Tick
        If Me.bRunning = True Then
            Try
                Dim t As New Thread(New ThreadStart(AddressOf DoURL))
                t.IsBackground = True
                t.Start()
            Catch ex As Exception
                MsgBox("tmrRequests_Tick exception: " & ex.ToString)
            End Try
        End If
    End Sub

This is the whole solution, basically.

Thanks!

BogusException
Author
28 Jul 2006 9:34 PM
Kim Greenlee
Since the problem seems to be that you are not seeing the number of threads
you are expecting to see, I recommend that you look at a couple things.

Set breakpoints at DoUrl()->r.DoRequest() and at
tmrRequests_Tick()->t.Start().  The reason for these two breakpoints is to
see what is really happening.   It is possible that DoUrl() returns so
quickly that by the time you’ve finished creating all the threads that 9 of
them have already finished.  Remember, with thread debugging its all about
timing.  So by stepping through these two breakpoints you will have a chance
to experience the context switching.  This should give you an idea of whether
the threads are truly being created.  I suspect that you’ll find that the
threads are being created as expected but that the underlying work that the
thread is attempting is not running the way you think it should. 

After you’ve looked at the context switching, I suggest that you next drill
down into the DoRequest() method by setting a breakpoint at the beginning of
the method and watching what happens between each call.  If you don’t see
anything out of the ordinary, you may be slowing down execution enough that
everything works as you expected.  So remove any breakpoints and add logging
to the method.  I find that because threading bugs are so tied to timing that
log files are a great tool for understanding exactly what is happening. 
Depending on your application you could also write to a console, but that
will not display the results as “true” as you might need because the console
itself gets a context switch and displays data that is in its buffer on that
switch.

Good luck,

Kim Greenlee



--
digipede - Many legs make light work.
Grid computing for the real world.
http://www.digipede.net
http://krgreenlee.blogspot.net