are objects assosiated with the thread they are created on?

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Are objects implicitly stored in the TLS of the currently running thread?
When creating multithreaded applications i get errors when accessing data
from a different thread than the thread used to create the objects (which is
easely fixed by calling Invoke()). Also, is there a way to acces the thread
which created the thread, or in other words: is there a parent/child
relationship between threads?
 
MariusI said:
Are objects implicitly stored in the TLS of the currently running
thread? When creating multithreaded applications i get errors when
accessing data from a different thread than the thread used to create
the objects (which is easely fixed by calling Invoke()). Also, is
there a way to acces the thread which created the thread, or in other
words: is there a parent/child relationship between threads?

threads are just run contexts in the same code. You've to understand a
couple things:
- variables created in a routine's scope (i.e local scope) are created
in the stack frame of the caller. This means that every thread calling
a method Foo and Foo creates a local variable bar will have its own bar
instance, not sharing it with any other thread.
- variables created in a program scope (or lets say appDomain scope),
or better: in the scope that contains the thread spawn code, are shared
among threads as these aren't created in the stackframe of the thread,
because they're not locally created.

So if you have a class member variable _bar and you create that in a
method Foo, calling the method Foo with multiple threads will make
every thread access the same class member variable _bar.

Objects aren't 'associated' with a thread normally, unless as said
they're created locally in a method scope. There's one exception:
Windows UI resources.

By design, the windows UI is single threaded. It internally associates
resources to a single thread, namely the calling thread. This means
that if you create a button in thread A, the HWND (and other resources,
or better: Handles) are associated with A. If you then want to do
something with the button created by A from thread B, you have to do
that through A, via Invoke, because B doesn't 'own' the handles of the
button. Everyone who has done some win32 programming knows that if you
request the HDC for a window from different threads, you'll get
different values, and each thread has to use their own HDC, not another
thread's one.

Not all applications play nice. You can see that in action when some
application runs and an icon changes in explorer, or leaks memory
(tiny).

So rules of thumb:
1) locally created variables in methods are local to a thread, every
thread has its own versions
2) globally created variables are global to every thread: all threads
share the same version
3) Windows UI resources are associated to the calling thread and you
should use Invoke to use them, even though you use them in a scenario
where 2) would be true. (example: you have a worker thread which wants
to update a progress bar in a form on the main thread. You can but
don't do that directly, use invoke.

FB

--
 
Thank you, this explains things to a great deal, but my second question
remains unanswered: "Also, is there a way to acces the thread which created
the thread, or in other words: is there a parent/child relationship between
threads?"
 
MariusI said:
Thank you, this explains things to a great deal, but my second question
remains unanswered: "Also, is there a way to acces the thread which created
the thread, or in other words: is there a parent/child relationship between
threads?"

Not that I'm aware of, and not that the .NET API exposes.
 
MariusI said:
Thank you, this explains things to a great deal, but my second
question remains unanswered: "Also, is there a way to acces the
thread which created the thread, or in other words: is there a
parent/child relationship between threads?"

No. A thread is a thread, in a process, all threads are equal. Some
will qualify one thread as the 'main' thread and see the other threads
as 'worker threads' but technically they're the same.

FB


--
 
Frans Bouma said:
No. A thread is a thread, in a process, all threads are equal. Some
will qualify one thread as the 'main' thread and see the other threads
as 'worker threads' but technically they're the same.

One slight difference - you can't make the "main" thread a background
thread (or at least, it doesn't have any effect). For instance:

using System;
using System.Threading;

public class Test
{
static void Main(string[] args)
{
Thread t = new Thread (new ThreadStart(KeepCounting));
t.IsBackground = true;
t.Start();
t.IsBackground = true;
// The process should immediately finish now...
Thread.Sleep(10000);
}

static void KeepCounting()
{
int i=0;
while (true)
{
Console.WriteLine (i++);
Thread.Sleep(1000);
}
}
}
 
Jon said:
Frans Bouma said:
No. A thread is a thread, in a process, all threads are equal. Some
will qualify one thread as the 'main' thread and see the other
threads as 'worker threads' but technically they're the same.

One slight difference - you can't make the "main" thread a background
thread (or at least, it doesn't have any effect). For instance:

using System;
using System.Threading;

public class Test
{
static void Main(string[] args)
{
Thread t = new Thread (new ThreadStart(KeepCounting));
t.IsBackground = true;
t.Start();
t.IsBackground = true;
// The process should immediately finish now...
Thread.Sleep(10000);
}

static void KeepCounting()
{
int i=0;
while (true)
{
Console.WriteLine (i++);
Thread.Sleep(1000);
}
}
}

Ok, but the 'main' thread isn't a higher-order thread than the thread
you created, at least not for the system it runs on. Windows schedules
threads, based on their priority. So unless you kick the mainthread's
priority, it won't be a 'higher order' thread of some kind, which was
what I argued.

That's the technical side of things. Semantically, it's another story
of course, as you there have a 'main' thread and 'worker' threads,
which act as if there's some kind of ranking system in place ;)

FB

--
 
Frans Bouma said:
Ok, but the 'main' thread isn't a higher-order thread than the thread
you created, at least not for the system it runs on. Windows schedules
threads, based on their priority. So unless you kick the mainthread's
priority, it won't be a 'higher order' thread of some kind, which was
what I argued.
Indeed.

That's the technical side of things. Semantically, it's another story
of course, as you there have a 'main' thread and 'worker' threads,
which act as if there's some kind of ranking system in place ;)

Sort of - of course, there's nothing to say that the thread that starts
off in Main has to be the UI "main" thread, etc :)
 
Back
Top