473,396 Members | 2,158 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Does threadpool utilize a memory barrier?

It occurs to me that if I have a work object that gets executed via
QueueUserWorkItem AND the work proc accesses only that object's
instance data I STILL may have to lock because the object constructor
ran in a different thread. That therefpre means that without a lock
the threadpool thread might not get the correct view of the instance
data. (Specifically, it might still be seen as null).

Has this ever come up before?

Thanks,
Tom

Nov 17 '05 #1
16 2606
Tom,

No, it has not. An object can not be accessed in a constructor by any
other thread BUT the thread that the object is being constructed on.

If you are assigning the object to a field that is shared by two
different methods in the ThreadPool, then yes, it is possible. However, you
should encapsulate access to the field in a property, which will guarantee
that you have only one instance (it will lock on something, check to see if
null, and create the instance if necessary).

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

<NO***********@lycos.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
It occurs to me that if I have a work object that gets executed via
QueueUserWorkItem AND the work proc accesses only that object's
instance data I STILL may have to lock because the object constructor
ran in a different thread. That therefpre means that without a lock
the threadpool thread might not get the correct view of the instance
data. (Specifically, it might still be seen as null).

Has this ever come up before?

Thanks,
Tom

Nov 17 '05 #2
<NO***********@lycos.com> wrote:
It occurs to me that if I have a work object that gets executed via
QueueUserWorkItem AND the work proc accesses only that object's
instance data I STILL may have to lock because the object constructor
ran in a different thread. That therefpre means that without a lock
the threadpool thread might not get the correct view of the instance
data. (Specifically, it might still be seen as null).

Has this ever come up before?


Yes, it's been asked, and to be honest there isn't a satisfactory
answer. I very, very much doubt that the thread-pool is able to work
without there being a memory barrier involved somewhere - after all,
the delegate itself has to be passed between threads, so there must be
*some* synchronization. Having said that, the documentation doesn't
specify it.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 17 '05 #3

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
<NO***********@lycos.com> wrote:
It occurs to me that if I have a work object that gets executed via
QueueUserWorkItem AND the work proc accesses only that object's
instance data I STILL may have to lock because the object constructor
ran in a different thread. That therefpre means that without a lock
the threadpool thread might not get the correct view of the instance
data. (Specifically, it might still be seen as null).

Has this ever come up before?


Yes, it's been asked, and to be honest there isn't a satisfactory
answer. I very, very much doubt that the thread-pool is able to work
without there being a memory barrier involved somewhere - after all,
the delegate itself has to be passed between threads, so there must be
*some* synchronization. Having said that, the documentation doesn't
specify it.


Just to add on: Since the documentation and specification, to my knowledge
anyway, don't define it, you really should ensure *your* code is safe.
Without a specificiation I could see subtle issues coming up across
platforms or implementations.
Nov 17 '05 #4
Nicholas,

You stated:

"If you are assigning the object to a field that is shared by two
different methods in the ThreadPool, then yes, it is possible."

That is not really what I was trying to describe, so I apologize for
not being more clear. Let me restate the problem.

An object "worker" is created on thread "A". That is to say, its
constructor is called on thread "A", with args X, Y, and Z getting
passed in. Aside from the constructor, thread "A" never accesses the
"worker" again. Now the "worker" is invoked via the threadpol
(QueueUserWorkItem) on thread "B". Now even though thread "B" is the
only one to access the data from now on in this stand-alone worker
object, technically the data was assigned via the constructor that
obviously ran on a different thread. So we have a potentional
threading issue right?

Put yet another way, it is *impossible* to create a worker object to be
executed on the framework threadpool without obviously creating it on a
seperate thread. So it seems that one use locking when using the
threadpool even if only the thread from the threadpool performs
operations/etc on the work data.

Thanks,
Tom

Nov 17 '05 #5
Jon and Daniel,

Thanks for your help. It seems to me there must be at least a dozen
bad examples of using the ThreadPool on the MSDN if we must use locking
in this case.

Next question, is it sufficient to just lock once in the constructor
and once at the start of the threaded work proc to have the proper
flushes occur on the memory cahce of the two threads involved? It
seems wasteful to reaquire the lock over and over in the work procdure
once the values are in a know good state.

Thanks again,
Tom

Nov 17 '05 #6
Tom,

You don't have an issue here with worker being created on thread A.
Once you create the object, if you pass it to another object, there is no
affinity to the thread it was created on (unless you impose one, like
Controls in Windows Forms). It's just another object.

What you do have to worry about is X, Y, and Z. If you store those in
the class and call them, the calls are coming in from another thread, and
access to them has to be synchronized (either by you, or the instances
themselves).

Other than that, you shouldn't have a problem. Since that instance will
only be accessed in the thread pool, you don't have to worry about other
fields you have (besides the fields that X, Y, and Z are assigned to).
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
<NO***********@lycos.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
Nicholas,

You stated:

"If you are assigning the object to a field that is shared by two
different methods in the ThreadPool, then yes, it is possible."

That is not really what I was trying to describe, so I apologize for
not being more clear. Let me restate the problem.

An object "worker" is created on thread "A". That is to say, its
constructor is called on thread "A", with args X, Y, and Z getting
passed in. Aside from the constructor, thread "A" never accesses the
"worker" again. Now the "worker" is invoked via the threadpol
(QueueUserWorkItem) on thread "B". Now even though thread "B" is the
only one to access the data from now on in this stand-alone worker
object, technically the data was assigned via the constructor that
obviously ran on a different thread. So we have a potentional
threading issue right?

Put yet another way, it is *impossible* to create a worker object to be
executed on the framework threadpool without obviously creating it on a
seperate thread. So it seems that one use locking when using the
threadpool even if only the thread from the threadpool performs
operations/etc on the work data.

Thanks,
Tom

Nov 17 '05 #7
Tom,

The constructor is only accessed by one thread, ever. In this sense,
you never have to use lock in the constructor. If you are using lock in the
constructor, you are going to lock on something other than your internal
state (since you created it, and you can't lock on this, because "this"
could not have been possibly assigned somewhere else to be used as a lock
either), and it is better to have something else managing the locks to that
(encapsulate it).
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

<NO***********@lycos.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
Jon and Daniel,

Thanks for your help. It seems to me there must be at least a dozen
bad examples of using the ThreadPool on the MSDN if we must use locking
in this case.

Next question, is it sufficient to just lock once in the constructor
and once at the start of the threaded work proc to have the proper
flushes occur on the memory cahce of the two threads involved? It
seems wasteful to reaquire the lock over and over in the work procdure
once the values are in a know good state.

Thanks again,
Tom

Nov 17 '05 #8
Nicholas Paldino [.NET/C# MVP] <mv*@spam.guard.caspershouse.com> wrote:
The constructor is only accessed by one thread, ever. In this sense,
you never have to use lock in the constructor. If you are using lock in the
constructor, you are going to lock on something other than your internal
state (since you created it, and you can't lock on this, because "this"
could not have been possibly assigned somewhere else to be used as a lock
either), and it is better to have something else managing the locks to that
(encapsulate it).


"this" can certainly be used in other threads while the originally
constructing thread is running - for instance if the constructor
creates a thread and starts it during the constructor.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 17 '05 #9
<NO***********@lycos.com> wrote:
Thanks for your help. It seems to me there must be at least a dozen
bad examples of using the ThreadPool on the MSDN if we must use locking
in this case.

Next question, is it sufficient to just lock once in the constructor
and once at the start of the threaded work proc to have the proper
flushes occur on the memory cahce of the two threads involved? It
seems wasteful to reaquire the lock over and over in the work procdure
once the values are in a know good state.


You need a memory barrier after you've made the last change in the
thread "providing" the value, and a memory barrier before you access
any other data in the thread "consuming" the value. You only need to do
it once.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 17 '05 #10
Jon,

Agreed, but people who do that should pretty much be shot.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Nicholas Paldino [.NET/C# MVP] <mv*@spam.guard.caspershouse.com> wrote:
The constructor is only accessed by one thread, ever. In this sense,
you never have to use lock in the constructor. If you are using lock in
the
constructor, you are going to lock on something other than your internal
state (since you created it, and you can't lock on this, because "this"
could not have been possibly assigned somewhere else to be used as a lock
either), and it is better to have something else managing the locks to
that
(encapsulate it).


"this" can certainly be used in other threads while the originally
constructing thread is running - for instance if the constructor
creates a thread and starts it during the constructor.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Nov 17 '05 #11
Tom,

Just so we're all on the same page I assume your question can be better
undersood by considering the following example:

class Test
{
private static object someObject = null;

static void Main()
{
someObject = new Object();
ThreadPool.QueueUserWorkItem(new WaitCallback(WorkItem));
Console.ReadLine();
}

static void WorkItem(object state)
{
if (someObject == null)
{
// Could this really happen?
Console.WriteLine("Foo");
}
else
{
Console.WriteLine("Bar");
}
}
}

The question is whether or not the write to someObject will be seen by
the WorkItem method right? Is it possible that "Foo" could be written
to the console?

I agree with Jon, I think it's very likely that the ThreadPool creates
a memory barrier internally and thus "Foo" would never be written.

Brian

NO***********@lycos.com wrote:
It occurs to me that if I have a work object that gets executed via
QueueUserWorkItem AND the work proc accesses only that object's
instance data I STILL may have to lock because the object constructor
ran in a different thread. That therefpre means that without a lock
the threadpool thread might not get the correct view of the instance
data. (Specifically, it might still be seen as null).

Has this ever come up before?

Thanks,
Tom


Nov 17 '05 #12
*** Inlined ***

"You need a memory barrier after you've made the last change in the
thread "providing" the value, "

*** Hence the lock in the constructor, since that is right after the
last change, as you asy "providing the value". ***

"and a memory barrier before you access
any other data in the thread "consuming" the value. You only need to
do
it once. "
*** Hence the second half of my idea to lock once at the start of my
work proc ***

*** And just to be clear, I know that no other thread is going to touch
the data while I'm in the constructor. The point of the lock in the
constructor is just to create a memory barrier. The same for the lock
at the start of the work proc. It just forces a memory barrier.

Given the originaly advice of using locking since the docos don't say
there is a memroy barrier, my current goal is to NOT lock on every
access of the data since I know that no other thread will ever touch
the work data once I begin processing. What I'd like to know is if I
can accomplish this goal by using just two locks instead of thousands
(if I access those variables via locked properties during the work
procedure).

Tom

Nov 17 '05 #13
Brian,

This is a bit closer, but your example is about right.
class Worker
{

// test kicker
static void Main()
{
arg = new Object();
worker = new Worker(arg);
ThreadPool.QueueUserWorkItem(new WaitCallback(worker.Process));
Console.ReadLine();
}

// instance data
private object someWorkData;

public Worker(object arg)
{
someWorkData = arg;
}
public void Process(object state)
{
if (someWorkData == null)
{
// Could this really happen?
Console.WriteLine("Foo");
}
else
{
Console.WriteLine("Bar");
}

while (true)
{
// use someWorkData over and over...
}

}

}

Nov 17 '05 #14
To be specifc, this example locks twice, just as you implied was
needed. Is this the bare minimum I need to be threadsafe in the
thread-pool situation?

class Worker
{

private object m_Lock = new object();

// instance data
private object someWorkData;

public Worker(object arg)
{
// lock here just for a memory barrier
lock(m_Lock)
{
someWorkData = arg;
}
}

public void Process()
{

object localArg;

// lock here just for a memory barrier
lock(m_Lock)
{
localArg = someWorkData;
}

while (true)
{
// use slocalArg over and over...
}

}

}

Nov 17 '05 #15
Nicholas,

It is specifically X, Y, and Z that I am asking about.

1. Do I need to protect X, Y, and Z or is there a memory barrier.

2. If there is no memory barrier in play, then I'd like to NOT lock on
each access of these three fields over and over again because I know
that (aside from when they were passed in during construction) the only
thread that touches them is the worker thread.

Thanks!
Tom

PS - As an aside, I've been told that a thread start has an implicit
memory barrier (which is good to know) but I'd like to know were to
specifically look to learn this kind of detail. The standard .NET
docos don't mention such details as that (or such details as my
original question) and usually like to do such research myself instead
of bothering you fine people :)

Nov 17 '05 #16
<NO***********@lycos.com> wrote:

<snip>
Given the originaly advice of using locking since the docos don't say
there is a memroy barrier, my current goal is to NOT lock on every
access of the data since I know that no other thread will ever touch
the work data once I begin processing. What I'd like to know is if I
can accomplish this goal by using just two locks instead of thousands
(if I access those variables via locked properties during the work
procedure).


Yes, that should be fine.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Nov 17 '05 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

38
by: Martin Marcher | last post by:
Hi, I've read several questions and often the answer was 'C knows nothing about .' So if C knows that little as some people say, what are the benefits, I mean do other languages know more...
74
by: Suyog_Linux | last post by:
I wish to know how the free()function knows how much memory to be freed as we only give pointer to allocated memory as an argument to free(). Does system use an internal variable to store allocated...
1
by: Tim Begin | last post by:
I am attempting to use the ThreadPool.SetMinThreads method as shown in the MSDN example code: int minWorker, minIOPort; int newWorker,newIOPort; ThreadPool.GetAvailableThreads(out minWorker, out...
31
by: William Stacey [MVP] | last post by:
Here is an interesting writing on memory barriers. Not sure if this helps my understanding or raises more questions, but interesting... ...
58
by: Larry David | last post by:
Ok, first of all, let's get the obvious stuff out of the way. I'm an idiot. So please indulge me for a moment. Consider it an act of "community service".... What does "64bit" mean to your friendly...
0
by: Ryan Linneman via .NET 247 | last post by:
I have a simple program to read data from a touchscreen overEthernet using a custom DLL provided by the touchscreenmanufacturer, and I want to read this data using the threadpool.When I use the...
3
by: Kevin | last post by:
Using this: http://msdn2.microsoft.com/en-us/library/3dasc8as(VS.80).aspx as an example I have a question concerning the reuse of objects. In the example 10 instances of the Fibonacci class...
34
by: Creativ | last post by:
Why does Thread class not support IDisposable? It's creating quite some problem. Namely, it can exhaust the resource and you have not control over it.
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.