Thread safety

A

arun.darra

Are the following thread safe:

1. Assuming Object is any simple object
Object* fn()
{
Object *p = new Object();
return p;
}

2. is return by value thread safe?

3. int *p = new int
is this thread safe?

Thanks
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

Are the following thread safe:

This is not a question for this group, since C++ does not define
threads, you should ask such questions in a group for your platform/
threading library.
1. Assuming Object is any simple object
Object* fn()
{
Object *p = new Object();
return p;
}

If the allocator is thread-safe then yes.
2. is return by value thread safe?

Everything on the stack should be thread-safe by nature.
3. int *p = new int
is this thread safe?

See 1.
 
D

d65yan

Are the following thread safe:
1. Assuming Object is any simple object
Object* fn()
{
Object *p = new Object();
return p;

}
about this(1)i dont see the harm, even doe i woldnt do it so,
2. is return by value thread safe?

3. int *p = new int
and this, i thinck it's meaningless.
 
I

Inso Reiges

Are the following thread safe:

1. Assuming Object is any simple object
Object* fn()
{
Object *p = new Object();
return p;

}

2. is return by value thread safe?

3. int *p = new int
is this thread safe?

Thanks

Each thread has it`s own stack and register frame. So everything that
does not access globally allocated objects is safe. In your code, as
it is, only the third case looks like its in a global space (again, as
it is in your post).
 
G

Gianni Mariani

Are the following thread safe:

Assuming you're using either GCC, VC++ or the Intel compiler...
1. Assuming Object is any simple object
Object* fn()
{
Object *p = new Object();
return p;
}

Safe if you use the supplied new operator.
2. is return by value thread safe?

Safe if the copy constructor is thread safe.
3. int *p = new int
is this thread safe?

Safe assuming that p is not used before it is initialized.
 
A

arun.darra

Assuming you're using either GCC, VC++ or the Intel compiler...




Safe if you use the supplied new operator.




Safe if the copy constructor is thread safe.




Safe assuming that p is not used before it is initialized.



Thanks for the reply... i just have 2 quick question:

1. You said that if i use the default new operator then using
Object *p = new Object();
is thread safe right...

but if i have a condition like:
If(thread-1)
Object1* p1 = new Object1();
else if(thread2)
Object2* p1 = new Object2();

and if both thread1 and thread2 are active at the same time and
running the above code then will new still be thread safe?

2. Is the following thread safe:
void fn()
{
static Object o;
}
assuming multiple threds are active
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

Thanks for the reply... i just have 2 quick question:

1. You said that if i use the default new operator then using
Object *p = new Object();
is thread safe right...

but if i have a condition like:
If(thread-1)
Object1* p1 = new Object1();
else if(thread2)
Object2* p1 = new Object2();

and if both thread1 and thread2 are active at the same time and
running the above code then will new still be thread safe?

Since p1 is on the stack of the thread running (and thus local to the
thread) there should be no problem. On the other hand if p1 was a global
variable (and we assume that you can assign a pointer of both type
Object1* and type Object2*) then you would have a problem unless you
provide some mediation of access to p1.
 
G

Gianni Mariani

1. You said that if i use the default new operator then using
Object *p = new Object();
is thread safe right...

but if i have a condition like:
If(thread-1)
Object1* p1 = new Object1();
else if(thread2)
Object2* p1 = new Object2();

This is no different, is it ?
and if both thread1 and thread2 are active at the same time and
running the above code then will new still be thread safe?

2. Is the following thread safe:
void fn()
{
static Object o;
}
assuming multiple threds are active

On GCC (maybe on others now), static local variable initialization is
thread safe. It is not thread safe on most platforms I know of. The
GCC support may be a little buggy on some more esoteric platforms.
Accessing 'o' is definitely not thread safe.

G
 
J

Jim Langston

Thanks for the reply... i just have 2 quick question:

1. You said that if i use the default new operator then using
Object *p = new Object();
is thread safe right...

but if i have a condition like:
If(thread-1)
Object1* p1 = new Object1();
else if(thread2)
Object2* p1 = new Object2();

and if both thread1 and thread2 are active at the same time and
running the above code then will new still be thread safe?

Each thread creates it's own local Object *p since it's declared locally.
Each thread can do what it wants to it since other threads, at this point,
can't touch the threads copy. What you do with it when you return it is
another matter.
2. Is the following thread safe:
void fn()
{
static Object o;
}
assuming multiple threds are active

Well, it is safe in this code, since you're not doing anything with o I
believe. Once you try to access o in the function, then I dont' believe
it's thread safe since all threads would share the same instance of o.
 
J

James Kanze

Are the following thread safe:
1. Assuming Object is any simple object
Object* fn()
{
Object *p = new Object();
return p;
}

What does your compiler documentation say? If the compiler
doesn't specify the thread safety guarantees, nothing is thread
safe.

Note that many compilers specify this indirectly, e.g. by
claiming Posix conformance. And while Posix doesn't specify a
C++ binding, it's generally "understood" that new should have
the same guarantees as malloc. You can thus call the above from
multiple threads without any particular precautions.
2. is return by value thread safe?

If the compiler guarantees it, e.g. by being Posix conform. If
the type has a user defined copy constructor, of course, it
depends on what is in it. (The copy constructor for std::string
in g++ is currently NOT thread safe.)
3. int *p = new int
is this thread safe?

What does your compiler documentation say. If it is Posix
conformant (and presumably Windows conformant), then yes.

Note that you cannot talk about the thread safety of isolated
bits of code. Thread safety is a contract, to be met by both
parties. Unless the compiler/library documents what it
guarantees, and what your responsibilities are, then it is not
thread safe. If it documents the contract, it is, but it is up
to you to respect your end of it.
 
G

Gianni Mariani

Jim Langston wrote:
....
Well, it is safe in this code, since you're not doing anything with o I
believe.

Only GCC (v4.0 or better) will work correctly (modulo a bug on some
platforms).

Construction of o is done when control first passes though the
definition. If two threads go through simultaneously, you can (and
often do) have construction happening twice. Not only that, it can also
fail if two separate static locals are initialized at the same time on
some platforms.

I don't know if any compilers other than GCC try to enforce the
initialize once rule for static locals in multi threaded environments.
 
J

James Kanze

Jim Langston wrote:
Only GCC (v4.0 or better) will work correctly (modulo a bug on some
platforms).

Actually, all of the compilers I have access to EXCEPT g++ work
correctly here. The difference is that g++ claims that this
code is conform to its contract, the others say it isn't. If
you write code that is not conform to the contract given by the
compiler, it's not the compiler which is wrong, it's your code.
G++ claims to offer more, but at least on my most common
platform (Sun Sparc, under Solaris), there is a bug in the
generated code, which means that they don't meet their own
guarantee.

In practice, the guarantee is usually worthless anyway, since as
Jim points out, you're going to use the object, and will need a
lock for that, so you might as well just take it before the
declaration, and be done with it. A more interesting case would
be if the static were const.
Construction of o is done when control first passes though the
definition. If two threads go through simultaneously, you can (and
often do) have construction happening twice. Not only that, it can also
fail if two separate static locals are initialized at the same time on
some platforms.
I don't know if any compilers other than GCC try to enforce
the initialize once rule for static locals in multi threaded
environments.

I suspect that most compilers are waiting 1) to see what the
standard will require here, and 2) to see what definition might
actually be useful. Having the compiler generate
synchronization code is pessimization (paying for something you
don't need) if I know that the first call will occur before
threading has started (often the case in my code), or if I need
a lock in the function anyway, in order to use the object. On
the other hand, having the compiler ensure whatever
synchronization necessary may be safer, especially where const
objects are concerned.
 
G

Gianni Mariani

James Kanze wrote:
....
Actually, all of the compilers I have access to EXCEPT g++ work
correctly here. The difference is that g++ claims that this
code is conform to its contract, the others say it isn't.

Rephrase that please.
... If
you write code that is not conform to the contract given by the
compiler, it's not the compiler which is wrong, it's your code.

Exactly what question are you answering ?
G++ claims to offer more, but at least on my most common
platform (Sun Sparc, under Solaris), there is a bug in the
generated code, which means that they don't meet their own
guarantee.

Yes - I stated it's buggy on some platforms, thanks. One day it will be
fixed if there is a bug filed. I don't remember if you filed the bug here.
In practice, the guarantee is usually worthless anyway, since as
Jim points out, you're going to use the object, and will need a
lock for that, so you might as well just take it before the
declaration, and be done with it. A more interesting case would
be if the static were const.

Oh, I disagree. I have seen plenty of production code where this has
been an issue. The object may itself be thread safe but the
initialization is not.

....
I suspect that most compilers are waiting 1) to see what the
standard will require here, and 2) to see what definition might
actually be useful. Having the compiler generate
synchronization code is pessimization (paying for something you
don't need) ...

Most platforms today already support some kind of thread safe guarantees
which is already a pessimization. I doubt that a one-time startup cost
of performing a little synchronization is going to exhibit a noticeable
overhead.
.... if I know that the first call will occur before
threading has started (often the case in my code), or if I need
a lock in the function anyway, in order to use the object.

Are you seriously saying that this is worth a few brain cycles to figure
out whether it's worth to optimize a few nanoseconds per static object
because you want to work out whether it's going to ever be needed ? I
don't see the value proposition here. I think I've consumed more time
in crafting this sentence than my computer ever will for synchronization
overhead for local static objects it will ever initialize by a wide margin.
... On
the other hand, having the compiler ensure whatever
synchronization necessary may be safer, especially where const
objects are concerned.

We agree on one thing. Cool.
 
J

James Kanze

James Kanze wrote:
Rephrase that please.

All of the compilers I know offer a set of guarantees with
repect to threading. G++, at least on a Sparc, doesn't conform
to the guarantees it claims to offer. IMHO, it's not a serious
problem, because it does conform to the guarantees every other
compiler offers, and and it has an option that explicitly says
that it won't even try to conform to any additional guarantees.

Since thread safety is largely a question of contract, g++, by
failing to meet its contract, is not thread safe. The other
compilers meet their contract, and so are.
Exactly what question are you answering ?

I'm pointing out that the original question is meaningless.
Yes - I stated it's buggy on some platforms, thanks. One day
it will be fixed if there is a bug filed. I don't remember if
you filed the bug here.

I haven't, although it is related to an earlier bug that I think
I filed. You're right, however, that I should check, and refile
if it isn't being handled.
Oh, I disagree. I have seen plenty of production code where this has
been an issue. The object may itself be thread safe but the
initialization is not.

I've seen it a lot with const objects, but not very often with
non-const. Implementing "thread-safety" at the object level is
generally counter productive---the granularity is too low.
Most platforms today already support some kind of thread safe guarantees
which is already a pessimization. I doubt that a one-time startup cost
of performing a little synchronization is going to exhibit a noticeable
overhead.

The synchronization is necessary each time you enter the block.

Just to be clearer here: I agree with your basic analysis that
the compiler should do the necessary. My own measures, under
Solaris, show that acquiring a lock on a mutex isn't that
expensive, at least if there's no contention, and so there's
really no reason for the compiler to try anything more
complicated (and if g++ used a statically initialized Mutex,
instead of trying to be clever, the implementation for Sparc
would work). But that's my personal opinion. As you no doubt
know, however, there is a wide spread attitude in the C++
community of "you don't pay for what you don't use". In this
case, since there will be a lot of cases where I'll need the
user level lock anyway, and so don't need the additional
compiler lock. So requiring it is requiring users to "pay for
what they don't need." Now, you and I may agree that in this
case, the cost is negligeable, largely affordable, and quite
acceptable in return for the benefit of increased safety, but I
think you'll find that there will be some resistance to it in
certain communitees in the committee. The situation is not as
bad as it used to be, but I wouldn't like to bet one way or the
other as to what the next version of the standard will actually
require.

And I'm afraid that I didn't make it clear that I was presenting
other people's arguments, and not my own opinion. The argument
of cost that I presented definitly exists, but IMHO, it is
largely outweighed by the avantages of requiring the compiler to
synchronize correctly.
Are you seriously saying that this is worth a few brain cycles to figure
out whether it's worth to optimize a few nanoseconds per static object
because you want to work out whether it's going to ever be needed ?

No. I'm saying that some people think so, and that "not paying
for what you don't use" has been a traditional criteria for C++.
I don't see the value proposition here. I think I've consumed
more time in crafting this sentence than my computer ever will
for synchronization overhead for local static objects it will
ever initialize by a wide margin.

It's easy to craft artificial examples where it would make a
measurable difference. I doubt that they occur much in the real
world, and I'm confident that the compiler vendors will provide
options to allow optimizing the rare and special cases where it
does.
We agree on one thing. Cool.

I think we basically agree overall on this one point.
Realistically, however, we are not the standards committee, and
the fact that we agree doesn't really mean much.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top