By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,694 Members | 1,847 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,694 IT Pros & Developers. It's quick & easy.

Only reading of variable vs. thread synchronisation

P: n/a
Does only reading (never writing) of a variable need thread synchronisation?
Thanks for help?

PS.
Anybody knows a Visual C++ news group?

Jun 27 '08 #1
Share this Question
Share on Google+
19 Replies


P: n/a
Hapa wrote:
Does only reading (never writing) of a variable need thread synchronisation?
Thanks for help?
That depends on whether you depend on the value read being up to date.

c.p.threads is a better place to ask, a similar question was asked there
recently check the archive.

--
Ian Collins.
Jun 27 '08 #2

P: n/a
"Hapa" <Ha**@apah.orgwrote in message
news:g2*************@news.t-online.com...
Does only reading (never writing) of a variable need thread
synchronisation?
Thanks for help?

PS.
Anybody knows a Visual C++ news group?

microsoft.public.vc.language

--
Scott McPhillips [VC++ MVP]

Jun 27 '08 #3

P: n/a
On Jun 4, 11:32 am, "Hapa" <H...@apah.orgwrote:
Does only reading (never writing) of a variable need thread
synchronisation?
Technically, it depends on the system, but under Posix (and I
think Windows as well), as long as no thread writes the object,
no synchronization is needed. As soon as any threat writes, all
accesses (even from threads which don't write) must be
synchronized.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #4

P: n/a

"Hapa" <Ha**@apah.orgwrote in message
news:g2*************@news.t-online.com...
Does only reading (never writing) of a variable need thread
synchronisation?
Thanks for help?

PS.
Anybody knows a Visual C++ news group?
It depends. When the variable access can be interrupted a thread switch can
occure. If you need more than one instruction to read _the_actual_data_ you
can read one part of the variable before and one after the read. This can
give strange results.

Where you need more than one instruction? Look at this variable named foo:

struct
{
int[100] a;
char b;
} foo;

/Helge
Jun 27 '08 #5

P: n/a
On 2008-06-04 15:59:30, James Kanze wrote:
As soon as any threat writes, [...]
thread === threat ? :)

Gerhard
Jun 27 '08 #6

P: n/a
On 2008-06-05 05:59:58, Helge Kruse wrote:
>Does only reading (never writing) of a variable need thread
synchronisation?
It depends. When the variable access can be interrupted a thread switch
can occure. If you need more than one instruction to read
_the_actual_data_ you can read one part of the variable before and one
after the read. This can give strange results.
Can you explain this more? Maybe an example? (Considering that no writes to
the variable in question occur during the observation period.)

Thanks,
Gerhard
Jun 27 '08 #7

P: n/a

"Gerhard Fiedler" <ge*****@gmail.comwrote in message
news:f8**************@gelists.gmail.com...
On 2008-06-05 05:59:58, Helge Kruse wrote:
>>Does only reading (never writing) of a variable need thread
synchronisation?
It depends. When the variable access can be interrupted a thread switch
can occure. If you need more than one instruction to read
_the_actual_data_ you can read one part of the variable before and one
after the read. This can give strange results.

Can you explain this more? Maybe an example? (Considering that no writes
to
the variable in question occur during the observation period.)
The thread switch can occur at any point of time, after each CPU
instruction. A normal read operation will prepare some address registers and
perform than the memory access. That is no problem, since the variable is at
the same address. But when the size of the variable is greater than the CPU
can fetch in one memory cycle you are in trouble.

See this example with pseudo code. Your variable is a 64 bit integer. You
have a CPU with one 32 bit address register R1 and some 32 bit data
registers R0,R3,R4. Reading the 64 bit integer is performed in this way. For
illustration purposes I use a simple if-statement.

; _int64 some_variable;
; if (0 == some_variable) { do something fatal }

1: move R1,offset some_variable ; loads 32 bit address to R1
2: move R3,@(R1) ; read low 32 bit part
3: move R4,@(R1+4) ; read high 32 bit
4: or R0,R3,R4 ; set any bit in R0 where the bit in R3
or
; R4 is set. R0 is 0 if no bit was set.
5: jump_if_not_zero some_where
6: ; here starts somthing fatal
.....
X: ; this is some_where

Each numbered line is one CPU instruction. The thread switch can occure
after each line.

If some_variable has a zero value, the "do something fatal" block should be
executed. Now lets set some_variable to 0x0000000100000000. Another thread
will decrement some_variable when it gets the CPU. If the thread switch
occures after line 2, you will read the low part of some_variable to R3.
When the working thread gets the CPU again, line 3 is executed. The value of
some_variable is now 0x00000000FFFFFFFF.

You will see that R3 is 0 since the low part was 0 before the thread switch
and R4 is 0 since the high part is 0 after the thread switch. You would say,
that some_variable was never zero four hours. But "do something fatal" will
be executed in the case. -- unexpected, unsecure, not threadsafe.

Regards,
Helge
Jun 27 '08 #8

P: n/a
On Jun 5, 3:20 pm, Gerhard Fiedler <geli...@gmail.comwrote:
On 2008-06-04 15:59:30, James Kanze wrote:
As soon as any threat writes, [...]
thread === threat ? :)
Now there's a freudian slip if I ever saw one. Threads do
introduce additional complexity, especially with regards to
ensuring correctness, and shouldn't be used unless the cost of
avoiding them outweighs this cost. (Like a lot of other
things---DLL's, TMP, etc.---, there seems to be a mode of using
them systematically, in every application, when a lot of the
time, you can do very well without them, with the results an
application that is simpler and more robust.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #9

P: n/a
On Jun 5, 4:43 pm, "Helge Kruse" <Helge.Kruse-nos...@gmx.netwrote:
"Gerhard Fiedler" <geli...@gmail.comwrote in message
news:f8**************@gelists.gmail.com...
On 2008-06-05 05:59:58, Helge Kruse wrote:
>Does only reading (never writing) of a variable need
thread synchronisation?
It depends. When the variable access can be interrupted a
thread switch can occure. If you need more than one
instruction to read _the_actual_data_ you can read one part
of the variable before and one after the read. This can
give strange results.
Can you explain this more? Maybe an example? (Considering
that no writes to the variable in question occur during the
observation period.)
The thread switch can occur at any point of time, after each
CPU instruction.
We all know that, but it's irrelevant here. The question
concerned what happens if no one writes to the variable. If no
thread modifies the variable, Posix (and Windows as well, I
think) guarantees that non-synchronized accesses work. You
don't need to know or understand more than that---the compiler
will do whatever is necessary for them to work. If any thread
modifies the variable, both Posix and Windows require
synchronization. Even if the variable is in a single machine
word (something you really can't know). Whether the variable is
in a single machine word or not is totally irrelevant here.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #10

P: n/a

"James Kanze" <ja*********@gmail.comwrote in message
news:a9**********************************@l42g2000 hsc.googlegroups.com...
>>Does only reading (never writing) of a variable need
thread synchronisation?
>The thread switch can occur at any point of time, after each
CPU instruction.
We all know that, but it's irrelevant here. The question
concerned what happens if no one writes to the variable.
Probably we will have to ask the OP what the question concerned. I
understand that
- there are threads
- one thread is only reading
- it's in question if the reading threads need any synchronization.

My common understanding of variables are use to store data, so they will be
written sometimes. We would use a constant instead if they are not written.
Since threads are in question I assumed that a write access can occur in
another thread. I read the (never writing) related to the the current
thread.

Hapa, can you clearify?
If any thread modifies the variable, both Posix and Windows
require synchronization. Even if the variable is in a single
machine word (something you really can't know). Whether the
variable is in a single machine word or not is totally
irrelevant here.
I disagree. After you have read a variable you have a copy of it (at least
to a CPU register). You have to define if a change after the read is
acceptible or not. Of not you need a thread synchronization. But even if it
is acceptible you can get in trouble as shown.

The compiler defines how data is stored. The statement, if a variable is in
a single word is compiler and CPU dependend. But you can know.
Regards,
Helge
--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #11

P: n/a
This variable is using something like global memory. This memory is written
by a third party app, which takes care that, we have no collision between
two apps. But now I have two or more threads whitin my app, which will only
read this global memory.

HP

"Helge Kruse" <He****************@gmx.netschrieb im Newsbeitrag
news:48**********************@newsspool2.arcor-online.net...
>
"James Kanze" <ja*********@gmail.comwrote in message
news:a9**********************************@l42g2000 hsc.googlegroups.com...
>>>Does only reading (never writing) of a variable need
thread synchronisation?

>>The thread switch can occur at any point of time, after each
CPU instruction.
>We all know that, but it's irrelevant here. The question
concerned what happens if no one writes to the variable.

Probably we will have to ask the OP what the question concerned. I
understand that
- there are threads
- one thread is only reading
- it's in question if the reading threads need any synchronization.

My common understanding of variables are use to store data, so they will
be written sometimes. We would use a constant instead if they are not
written. Since threads are in question I assumed that a write access can
occur in another thread. I read the (never writing) related to the the
current thread.

Hapa, can you clearify?
>If any thread modifies the variable, both Posix and Windows
require synchronization. Even if the variable is in a single
machine word (something you really can't know). Whether the
variable is in a single machine word or not is totally
irrelevant here.

I disagree. After you have read a variable you have a copy of it (at least
to a CPU register). You have to define if a change after the read is
acceptible or not. Of not you need a thread synchronization. But even if
it is acceptible you can get in trouble as shown.

The compiler defines how data is stored. The statement, if a variable is
in a single word is compiler and CPU dependend. But you can know.
Regards,
Helge
--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 27 '08 #12

P: n/a
On Jun 6, 10:29 am, "Helge Kruse" <Helge.Kruse-nos...@gmx.netwrote:
"James Kanze" <james.ka...@gmail.comwrote in message
news:a9**********************************@l42g2000 hsc.googlegroups.com...
>Does only reading (never writing) of a variable need
thread synchronisation?
The thread switch can occur at any point of time, after each
CPU instruction.
We all know that, but it's irrelevant here. The question
concerned what happens if no one writes to the variable.
Probably we will have to ask the OP what the question concerned. I
understand that
- there are threads
- one thread is only reading
- it's in question if the reading threads need any synchronization.
The question said "only reading, never writing".
My common understanding of variables are use to store data, so
they will be written sometimes.
Before threading is started, for example. I have a lot of
variables which are only read, never written, once threading has
started.
We would use a constant instead if they are not written.
Unless they need some sort of initialization, which can't be
done until main has been entered.

In practice, of course, a lot of the time, the variables will be
const.
Since threads are in question I assumed that a write access
can occur in another thread. I read the (never writing)
related to the the current thread.
That's not the way I interpreted his question, but I agree that
it could have been clearer.
Hapa, can you clearify?
If any thread modifies the variable, both Posix and Windows
require synchronization. Even if the variable is in a single
machine word (something you really can't know). Whether the
variable is in a single machine word or not is totally
irrelevant here.
I disagree.
You disagree with Posix?
After you have read a variable you have a copy of it (at least
to a CPU register). You have to define if a change after the
read is acceptible or not. Of not you need a thread
synchronization. But even if it is acceptible you can get in
trouble as shown.
The compiler defines how data is stored. The statement, if a
variable is in a single word is compiler and CPU dependend.
But you can know.
For a given compiler, on a given machine, you can sometimes
know. But it's irrelevant. Even if the variable is in a single
machine word, you need external synchronization. All Posix
offers here are the pthread_... functions; under Solaris, on a
Sparc, I'll occasionally drop down to assembler, and insert a
membar function myself, but only if it's really, really
necessary. And the compilers I use will never, under any
conditions, generate any membar instruction. (On IA-32
architecture, I think that the lock prefix---implied on the xchg
instruction, will automatically set up some sort of fence. But
again, it's never generated by the compiler, so you either have
to use inline assembler, or one of the system primitives.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orient�e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34
Jun 27 '08 #13

P: n/a
On Jun 6, 11:14 am, "Hapa" <H...@apah.orgwrote:
This variable is using something like global memory. This
memory is written by a third party app, which takes care that,
we have no collision between two apps. But now I have two or
more threads whitin my app, which will only read this global
memory.
Which still isn't too clear: by global memory, do you mean
shared memory, with the third party application in a separate
process? And when you say that there is no collision between
the applications, do you mean that there will never be two
processes accessing this shared memory at the same time? If
your process has exclusive access to this shared memory, there
is no need for any synchronization between threads within the
process; all the memory synchronization you need has occured
when you acquired access to the shared memory. (At least under
Posix; I'll less sure about Windows.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orient�e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34
Jun 27 '08 #14

P: n/a

"James Kanze" <ja*********@gmail.comwrote in message
news:46**********************************@k13g2000 hse.googlegroups.com...
>>Does only reading (never writing) of a variable need
thread synchronisation?
>Probably we will have to ask the OP what the question concerned. I
understand that
- there are threads
- one thread is only reading
- it's in question if the reading threads need any synchronization.
The question said "only reading, never writing".
And it said thread synchronization.
>Since threads are in question I assumed that a write access
can occur in another thread. I read the (never writing)
related to the the current thread.
That's not the way I interpreted his question, but I agree
that it could have been clearer.
Yes, we are interpreting something. Probably we do it in a wrong way.
If any thread modifies the variable, both Posix and Windows
require synchronization. Even if the variable is in a single
machine word (something you really can't know). Whether the
variable is in a single machine word or not is totally
irrelevant here.
>I disagree.
>You disagree with Posix?
No, never wrote this, I never cited Posix. I disagree that the single memory
access is irrelevant. The fact if you have single memory access it
determines the robustness of the read operation.
With a single memory access it is just impossible that the problem I
described.
>The compiler defines how data is stored. The statement, if a
variable is in a single word is compiler and CPU dependend.
But you can know.
For a given compiler, on a given machine, you can sometimes
know.
You're right. But that's not "something you really can't know". Well, you
said you can know.
But it's irrelevant. Even if the variable is in a single
machine word, you need external synchronization.
If a read operation is in a single memory read operation, what do you want
to synchronize?
I'll occasionally drop down to assembler, and insert a
membar function myself...
Sorry, dont know this membar function.
(On IA-32 architecture, I think that the lock prefix---implied
on the xchg instruction, will automatically set up some sort of fence.
Yes, the lock prefix can avoid interrupt (and thread switch) for an
instruction.
No, the xchg instruction is only used for read and modify. The question
concerned a read-only access.

Regards,
Helge
Jun 27 '08 #15

P: n/a
In article <b1949129-a110-4cba-9f8a-bc195dd0e8a3@
56g2000hsm.googlegroups.com>, ja*********@gmail.com says...

[ ... ]
Threads do
introduce additional complexity, especially with regards to
ensuring correctness, and shouldn't be used unless the cost of
avoiding them outweighs this cost.
Threads _often_ introduce cost -- then again, at times, they make a
design substantially _simpler_, particularly if the fundamental design
involves a lot of separate actions that rarely interact, and then only
in clearly specified ways.

Unfortunately, quite a few jobs aren't amenable to such a decomposition.
Even among those that are, the people writing the software may not use
it -- sometimes intentionally, others just because they missed it.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jun 27 '08 #16

P: n/a
On Jun 6, 1:19 pm, "Helge Kruse" <Helge.Kruse-nos...@gmx.netwrote:
"James Kanze" <james.ka...@gmail.comwrote in message
news:46**********************************@k13g2000 hse.googlegroups.com...
[...]
If any thread modifies the variable, both Posix and Windows
require synchronization. Even if the variable is in a single
machine word (something you really can't know). Whether the
variable is in a single machine word or not is totally
irrelevant here.
I disagree.
You disagree with Posix?
No, never wrote this, I never cited Posix.
But I did. The Posix standard says that whether the memory
accessed is a single word or not is irrelevant. If you
disagree, then you disagree with the Posix standard.
I disagree that the single memory access is irrelevant. The
fact if you have single memory access it determines the
robustness of the read operation.
Conforming to the specifications of your platform and your OS
determines the robustness of the read operation. Some platforms
may give you special guarantees for single word accesses;
Sparcs under Solaris don't, however, and as far as I know, nor
do Intels under Windows. If you know otherwise, you're free to
point me to the documentation which specifies it---I've been
looking for something more detailed and precise for Windows for
a long time now.
With a single memory access it is just impossible that the
problem I described.
What problem? Whether the data is in a single word or not, you
don't have any guarantee from Posix that it will work.
The compiler defines how data is stored. The statement, if
a variable is in a single word is compiler and CPU
dependend. But you can know.
For a given compiler, on a given machine, you can sometimes
know.
You're right. But that's not "something you really can't
know". Well, you said you can know.
You can know whether the data is on a single word, or not,
sometimes, although such guarantees are rare. You can't know
whether that will help.
But it's irrelevant. Even if the variable is in a single
machine word, you need external synchronization.
If a read operation is in a single memory read operation, what
do you want to synchronize?
Memory.
I'll occasionally drop down to assembler, and insert a
membar function myself...
Sorry, dont know this membar function.
It's the Sparc equivalent of a fence. It's used to synchronize
memory.
(On IA-32 architecture, I think that the lock
prefix---implied on the xchg instruction, will automatically
set up some sort of fence.
Yes, the lock prefix can avoid interrupt (and thread switch)
for an instruction.
At least on recent Intel processors, it does a lot more; it
generates some sort of implicit fence, ensuring memory
synchronization.
No, the xchg instruction is only used for read and modify.
And it has an implicit lock prefix, at least on more recent
Intel processors. (This means that a single xchg instruction
will probably be slower than a series of mov instructions if you
don't need the synchronization.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #17

P: n/a

"Helge Kruse" <He****************@gmx.netwrote in message
news:48***********************@newsspool4.arcor-online.net...
>
"James Kanze" <ja*********@gmail.comwrote in message
news:46**********************************@k13g2000 hse.googlegroups.com...
[...]
>>You disagree with Posix?
No, never wrote this, I never cited Posix. I disagree that the single
memory access is irrelevant. The fact if you have single memory access it
determines the robustness of the read operation.
With a single memory access it is just impossible that the problem I
described.
>>The compiler defines how data is stored. The statement, if a
variable is in a single word is compiler and CPU dependend.
But you can know.
>For a given compiler, on a given machine, you can sometimes
know.
You're right. But that's not "something you really can't know". Well, you
said you can know.
>But it's irrelevant. Even if the variable is in a single
machine word, you need external synchronization.
If a read operation is in a single memory read operation, what do you want
to synchronize?
May be misunderstanding you, but some algorihtms require a membar after a
read. For instance, take a classic single-producer/multi-consumer problem:
static atomicword data = 0;
static atomicword flag = 0;
Producer Thread
-------------------
ATOMIC_STORE(&data, 123);
ATOMIC_STORE(&flag, 1);
Consumer Threads
-------------------
while (! ATOMIC_LOAD(&flag)) {
sched_yield();
}
assert(ATOMIC_LOAD(&data) == 123);


The above has a major race-condition such that the store to the `flag' can
be hoisted up above the store to the `data'; the assertion _may_ fail. You
need memory synchronization on both the producer and consumer side to
properly solve this problem. Here is an example using SPARC memory barriers:
static atomicword data = 0;
static atomicword flag = 0;
Producer Thread
-------------------
ATOMIC_STORE(&data, 123);
MEMBAR #StoreStore;
ATOMIC_STORE(&flag, 1);
Consumer Threads
-------------------
for (;;) {
atomicword const _flag = ATOMIC_LOAD(&flag);
MEMBAR #LoadLoad;
if (_flag) { break; }
sched_yield();
}
assert(ATOMIC_LOAD(&data) == 123);


No we are assured that the store to `data' is rendered visible _before_ the
store to `flag'. And we know that the load from `flag' will not be reordered
wrt the subsequent load from `data'; the assertion is guaranteed to pass.
Memory barriers along with atomic operations are an essential aspect to
low-level concurrent programming techniques...
[...]

Jun 27 '08 #18

P: n/a
Helge Kruse wrote:
"James Kanze" <ja*********@gmail.comwrote:
>You disagree with Posix?
No, never wrote this, I never cited Posix. I disagree that the single memory
access is irrelevant. The fact if you have single memory access it
determines the robustness of the read operation.
With a single memory access it is just impossible that the problem I
described.
Aside from the standards issues already raised, consider a single
*misaligned* memory access requiring more than one bus cycle. A context
switch may occur during such a read.

--
Ian Collins.
Jun 27 '08 #19

P: n/a
On Jun 7, 11:19 pm, Ian Collins <ian-n...@hotmail.comwrote:
Helge Kruse wrote:
"James Kanze" <james.ka...@gmail.comwrote:
You disagree with Posix?
No, never wrote this, I never cited Posix. I disagree that
the single memory access is irrelevant. The fact if you have
single memory access it determines the robustness of the
read operation. With a single memory access it is just
impossible that the problem I described.
Aside from the standards issues already raised, consider a
single *misaligned* memory access requiring more than one bus
cycle. A context switch may occur during such a read.
Note that the problem can be extremely complex. Some hardware
doesn't support byte reads and writes (at the memory access
level): writing a char involves reading the word, replacing the
byte in question, then rewriting it. There was some discussion
during standardization about what to do about those---in the
end, the decision was that the implementation has to make them
work, one way or another. Which may mean some form of locking
and external synchronization on some machines. (On the other
hand, individual bit fields in a common structure are *NOT*
independent objects.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #20

This discussion thread is closed

Replies have been disabled for this discussion.