473,386 Members | 1,699 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,386 software developers and data experts.

Interlocked.Increment bug?

Hi,

Is there any known bug related to
Interlocked.Increment(ref var)?

My client report var's value going up and down in the client/server
multile-thread application. There are about 80 clients connect to one server
though TCP client.

But actully I never decrease var.

I change its type to volatile int and use lock to increase its value

lock(this.currentCountLock)
{
this.currentCount ++;
}
and handle over to my client. (It never decreases in my machine)
Thanks,
Ryan

BTW, why volatile can not be used with ref?
Dec 15 '06 #1
15 4741
"Ryan Liu" <ad********@online.sh.cnwrote:
>Is there any known bug related to
Interlocked.Increment(ref var)?
My client report var's value going up and down in the client/server
multile-thread application. There are about 80 clients connect to one server
though TCP client.
You'll have to give us a bit more context. For instance, this code:

int ptr=0;

[thread1]
int x = Interlocked.Increment(ref ptr);
Console.WriteLine(x);

[thread2]
int y = Interlocked.Increment(ref ptr);
Console.WriteLine(y);

can quite happily print "2,1", which looks as if it's decrementing,
even though in reality it isn't and the code is working fine.
Also, are you using the Int64 version or the Int32 version? I know
there's a recently-discovered bug in the Int64 version of
Interlocked.Add. It's conceivable that Interlocked.Increment(Int64)
might have the same bug?

--
Lucian
Dec 15 '06 #2

Ryan Liu wrote:
BTW, why volatile can not be used with ref?
Ryan,

Because the receiving method would not be aware of the volatile
semantics. Also, if you're always using a lock then there's no need to
mark the field as volatile.

Brian

Dec 15 '06 #3

"Lucian Wischik" <lu***@wischik.comwrote in message
news:u3********************************@4ax.com...
| "Ryan Liu" <ad********@online.sh.cnwrote:
| >Is there any known bug related to
| >Interlocked.Increment(ref var)?
| >My client report var's value going up and down in the client/server
| >multile-thread application. There are about 80 clients connect to one
server
| >though TCP client.
|
| You'll have to give us a bit more context. For instance, this code:
|
| int ptr=0;
|
| [thread1]
| int x = Interlocked.Increment(ref ptr);
| Console.WriteLine(x);
|
| [thread2]
| int y = Interlocked.Increment(ref ptr);
| Console.WriteLine(y);
|
| can quite happily print "2,1", which looks as if it's decrementing,
| even though in reality it isn't and the code is working fine.
|
|
| Also, are you using the Int64 version or the Int32 version? I know
| there's a recently-discovered bug in the Int64 version of
| Interlocked.Add. It's conceivable that Interlocked.Increment(Int64)
| might have the same bug?
|
| --
| Lucian

How can it decrement when you are calling two times Interlocked.Increment,
I'm I missing something here?

Willy.
Dec 15 '06 #4

"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:uP**************@TK2MSFTNGP02.phx.gbl...
|
| "Lucian Wischik" <lu***@wischik.comwrote in message
| news:u3********************************@4ax.com...
|| "Ryan Liu" <ad********@online.sh.cnwrote:
|| >Is there any known bug related to
|| >Interlocked.Increment(ref var)?
|| >My client report var's value going up and down in the client/server
|| >multile-thread application. There are about 80 clients connect to one
| server
|| >though TCP client.
||
|| You'll have to give us a bit more context. For instance, this code:
||
|| int ptr=0;
||
|| [thread1]
|| int x = Interlocked.Increment(ref ptr);
|| Console.WriteLine(x);
||
|| [thread2]
|| int y = Interlocked.Increment(ref ptr);
|| Console.WriteLine(y);
||
|| can quite happily print "2,1", which looks as if it's decrementing,
|| even though in reality it isn't and the code is working fine.
||
||
|| Also, are you using the Int64 version or the Int32 version? I know
|| there's a recently-discovered bug in the Int64 version of
|| Interlocked.Add. It's conceivable that Interlocked.Increment(Int64)
|| might have the same bug?
||
|| --
|| Lucian
|
| How can it decrement when you are calling two times Interlocked.Increment,
| I'm I missing something here?
|
| Willy.
|
|

Sorry forget my previous post, I misread the OP's question.

Willy.
Dec 15 '06 #5
No - it doesn't decrement, but it can *look* like it does, depending
on which thread runs hotter.

e.g.
* thread 1 increments and receives 1, and is then paused by the
scheduler
* thread 2 increments and receives 2
* thread 2 writes "2" to the console
* thread 1 wakes up and writes "1" to the console

it never decreases... just threading...

Of course, if you increment it enough times to overlflow int.MaxValue,
then that is different ;-p

Marc
Dec 15 '06 #6
I am not following that. You seem to be mixing locks and interlocked. Can
we see a better sample of what your talking about.

--
William Stacey [C# MVP]

"Ryan Liu" <ad********@online.sh.cnwrote in message
news:eh***************@TK2MSFTNGP02.phx.gbl...
| Hi,
|
| Is there any known bug related to
| Interlocked.Increment(ref var)?
|
| My client report var's value going up and down in the client/server
| multile-thread application. There are about 80 clients connect to one
server
| though TCP client.
|
| But actully I never decrease var.
|
| I change its type to volatile int and use lock to increase its value
|
| lock(this.currentCountLock)
| {
| this.currentCount ++;
| }
| and handle over to my client. (It never decreases in my machine)
|
|
| Thanks,
| Ryan
|
| BTW, why volatile can not be used with ref?
|
|
Dec 15 '06 #7
Thanks, Brain!

Then:

if the volatile variable is only be modified by var++ , then no need to use
lock to prevent it from not increasing value?

if variable can be modified by hardware, then volatile is still needed?

Thanks,
Ryan

"Brian Gideon" <br*********@yahoo.com????
news:11**********************@t46g2000cwa.googlegr oups.com...
>
Ryan Liu wrote:
BTW, why volatile can not be used with ref?

Ryan,

Because the receiving method would not be aware of the volatile
semantics. Also, if you're always using a lock then there's no need to
mark the field as volatile.

Brian

Dec 16 '06 #8
Hi William,

Yes, I thought Interlocked does implicit lock or it doesn't really useful,
especially the variable is only simply advance itself.

I have abstract code following. I have a brife explain here first.

It is a client/Server application. There are 3 roles runs on differant
machines: Worker, Manager, and ApplicationServer.

Each worker works on a Item at a time.
When worker done a Item, it notifies server, and server advances the
project's current count if it is a "success" Item.

Each worker owns a thread in ApplicationServer, AppServer
talks(listen/write) to worker though that thread.

ApplicatonServer also have another backend thread run on an interval base to
read projects current value and update Managers. It check an arraylist to
see what projects need update. The project id is added to this arraylist
when worker's thread change current count in appServer.

Actual application is much more complicated then this. The following is
original code, and I am changing code to the one in comments.

public class Project
{

....

//later add this: private readonly object currentCountLock = new object();
private int currentCount; //later add volatile
public int CurrentCount
{
get
{
return this.currentCount;
}

}

/// <summary>
/// advance current by 1, in a atomic mode
/// </summary>
private void AdvanceCurrentCount()
{

Interlocked.Increment(ref this.currentCount);
//lock(this.currentCountLock)
//{
//this.currentCount ++;
//}

this.CheckIfFullAndMarkPPIfSo();
}

//80 workers' thread call this when it receive notificaton from workers
public bool DoneAnItem( ...)
{
...
if(successEnd)
{
AdvanceCurrentCount();
}
server.InfoClientQuotaChange(this);
}
}
public class Server
{

private ArrayList statusChangedProjects= new ArrayList();

// register status changed project id in the ArrayList
// then there is another thread scan this ArrayList
// to find out which project status
internal void InfoClientQuotaChange(Project project)
{
lock(this.statusChangedProjects.SyncRoot)
{
this.statusChangedProjects.Add(project.projectId);
}
}
.........
//backend thread
while(true)
{
foreach(Project p in statusChangedProjects)
{

sb.Append(p.CurrentCount);

}

//send sb.ToString() to manager

Thead.Sleep(500);

}
}

Thanks,
Ryan
"William Stacey [C# MVP]" <wi************@gmail.comдÈëÓʼþ
news:OK**************@TK2MSFTNGP06.phx.gbl...
I am not following that. You seem to be mixing locks and interlocked.
Can
we see a better sample of what your talking about.

--
William Stacey [C# MVP]

"Ryan Liu" <ad********@online.sh.cnwrote in message
news:eh***************@TK2MSFTNGP02.phx.gbl...
| Hi,
|
| Is there any known bug related to
| Interlocked.Increment(ref var)?
|
| My client report var's value going up and down in the client/server
| multile-thread application. There are about 80 clients connect to one
server
| though TCP client.
|
| But actully I never decrease var.
|
| I change its type to volatile int and use lock to increase its value
|
| lock(this.currentCountLock)
| {
| this.currentCount ++;
| }
| and handle over to my client. (It never decreases in my machine)
|
|
| Thanks,
| Ryan
|
| BTW, why volatile can not be used with ref?
|
|


Dec 16 '06 #9
Thanks, everyone. I guess you guys are rignt, " looks as if it's
decrementing" is what happening.

I thought Interlocked does implicit lock or it doesn't really useful,
especially the variable is only simply advance itself.
And, Lucian, I am using Int32 version.

Ryan

"Marc Gravell" <ma**********@gmail.comдÈëÓʼþ
news:%2****************@TK2MSFTNGP06.phx.gbl...
No - it doesn't decrement, but it can *look* like it does, depending
on which thread runs hotter.

e.g.
* thread 1 increments and receives 1, and is then paused by the
scheduler
* thread 2 increments and receives 2
* thread 2 writes "2" to the console
* thread 1 wakes up and writes "1" to the console

it never decreases... just threading...

Of course, if you increment it enough times to overlflow int.MaxValue,
then that is different ;-p

Marc



Dec 16 '06 #10
Oh, on the second thought, I think that is not the case.

As said in another email in this conversation thread,
I have many threads advance the var,
and another single thread read it and show to the end user.

Then this "read" thead should never "looks as if it is decrementing" ...
"Ryan Liu" <ad********@online.sh.cnдÈëÓʼþ
news:Ob*************@TK2MSFTNGP02.phx.gbl...
Thanks, everyone. I guess you guys are rignt, " looks as if it's
decrementing" is what happening.

I thought Interlocked does implicit lock or it doesn't really useful,
especially the variable is only simply advance itself.
And, Lucian, I am using Int32 version.

Ryan

"Marc Gravell" <ma**********@gmail.comдÈëÓʼþ
news:%2****************@TK2MSFTNGP06.phx.gbl...
No - it doesn't decrement, but it can *look* like it does, depending
on which thread runs hotter.

e.g.
* thread 1 increments and receives 1, and is then paused by the
scheduler
* thread 2 increments and receives 2
* thread 2 writes "2" to the console
* thread 1 wakes up and writes "1" to the console

it never decreases... just threading...

Of course, if you increment it enough times to overlflow int.MaxValue,
then that is different ;-p

Marc



Dec 16 '06 #11

Ryan Liu wrote:
Thanks, Brain!

Then:

if the volatile variable is only be modified by var++ , then no need to use
lock to prevent it from not increasing value?
You still need to aquire a lock or use an interlocked operation. The
volatile keyword does not make any guarentees about atomicity. It has
more to do with when reads and writes of the variable occur.
>
if variable can be modified by hardware, then volatile is still needed?
Not necessarily. Any mechanism that produces a memory barrier should
be sufficient. Read the following article for more details.

http://www.yoda.arachsys.com/csharp/...latility.shtml

Brian

Dec 16 '06 #12
Ryan Liu <ad********@online.sh.cnwrote:
Then:

if the volatile variable is only be modified by var++ , then no need to use
lock to prevent it from not increasing value?
No - you still need a lock. Think of var++ as

var = var + 1;

Another thread could change the value of var between "var + 1" being
evaluated and "var" being assigned.
if variable can be modified by hardware, then volatile is still needed?
I'm not even sure if this is possible within managed code. Could you
give an example?

--
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
Dec 16 '06 #13
Ryan Liu <ad********@online.sh.cnwrote:
Yes, I thought Interlocked does implicit lock or it doesn't really useful,
especially the variable is only simply advance itself.
No - there's no lock involved. The point of Interlocked is to avoid
using a lock at all.
I have abstract code following. I have a brife explain here first.
<snip>

Unfortunately, abstract code is rarely detailed enough: with threading,
the devil is in the detail.

Personally, I'd ignore Interlocked and volatile as mechanisms and use
locks until you have evidence that the use of locks is a significant
performance hit. Getting it right with locks is non-trivial, but it's a
lot easier (IMO) than getting it right without locks.

--
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
Dec 16 '06 #14

"Jon Skeet [C# MVP]" <sk***@pobox.com????
news:MP************************@msnews.microsoft.c om...
Ryan Liu <ad********@online.sh.cnwrote:
Then:

if the volatile variable is only be modified by var++ , then no need to
use
lock to prevent it from not increasing value?

No - you still need a lock. Think of var++ as

var = var + 1;

Another thread could change the value of var between "var + 1" being
evaluated and "var" being assigned.
if variable can be modified by hardware, then volatile is still needed?

I'm not even sure if this is possible within managed code. Could you
give an example?

Just a general question, I think you are right, it is impossible for
managed code.

Thanks!
--
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

Dec 16 '06 #15
Ryan Liu <ad********@online.sh.cnwrote:

<snip>
Just a general question, I think you are right, it is impossible for
managed code.
"Volatile" means different things in different memory models. It has a
well-defined meaning in C#/.NET, but that's not the same as in C, for
instance.

--
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
Dec 16 '06 #16

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

Similar topics

14
by: Pierre | last post by:
Using the "volatile" keyword, creates a problem if I intend to use any of the interlocked APIs. The compiler generates an error if I use the following line, for example: ...
19
by: steve | last post by:
// What I want to do Use enumerated types with the Interlocked.Exchange methods Suggestions please // My estimation of problem Seems like Interlocked.Exchange only works with ints,...
3
by: George Ter-Saakov | last post by:
What is the purpose of having Interlocked.Increment if it does not work with variable declared as volatile. Here is my problem, Interlocked.Increment increments the variable in thread safe...
3
by: Ryan Liu | last post by:
Hi, Can some one tell the criteria I can used to decide use of Interlocked.Increment() vs volatile , which is better? Thanks a lot! Ryan
23
by: Anders Borum | last post by:
Hi! I am implementing a threaded producer / consumer pattern just for fun. I am using an internal counter to keep track of the produced / consumed items and am logging that information. I am...
5
by: Mark Salsbery [MVP] | last post by:
I have an member variable (int) that is accessed by multiple threads using Interlocked.Increment(), Interlocked.Decrement(), and read directly. Using volatile gives me "CS0420: a reference to a...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

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.