locking an int

D

Dan Holmes

Göran Andersson said:
Create an object in the class to use as identifier:

object _sync = new object();

Use the object for locking the code block accessing the counter:

// Lock the code. Since this is async IO more than
// 1 IO could be at this point need to make sure
// that the variable only gets accessed in a serial manner.
lock (_sync) {
//move to the next servant
if (++nextServantIndex >=
Properties.Settings.Default.Servants.Count) {
nextServantIndex = 0;
}
}

thanks for the clarification. I ended up changing approaches. I never liked the indexing method. I changed it to a
queue. Now i pull the first object from the queue and immediately put it back. then return the object. This seemed
simpler and had less "moving parts". I will change it to use a sync object like you exampled though. I think i
remember posted about not locking "this".

public class QsServants : List<QsServant>
{
private Queue<QsServant> servantQueue = new Queue<QsServant>();
public QsServant Next()
{
QsServant q = null;
lock (this)
{
q = servantQueue.Dequeue();
servantQueue.Enqueue(q);
}
return q;
}
/// <summary>
public void Initialize()
{
this.ForEach(delegate(QsServant q) { servantQueue.Enqueue(q); });
}
}
 
P

Paul

messaging in the future. We have a mixture of languages already. .net,
VB6, Java, C++ along with .net inside
SQLServer.

This statement itself proves there is no architectural plan.
 
P

Peter Duniho

Paul said:
lol moot not mute.....Absolutely right don't know what made me write it
mute.

I agree as a communication protocol TCP is pretty much cross platform where
I disagree is that re-inventing the wheel is a good thing. Most development
languages have support for SOAP or even HTTP communication this day and age,
even VB6 had SOAP support.

But you can't easily write a VB6 program that can receive SOAP-formatted
data structures from a .NET program. The very thing that makes the .NET
remoting technologies convenient to use -- built-in support for
serialization/deserialization of .NET objects -- makes it very
complicated to use those technologies with non-.NET peers.
Looking at the function in hand re-creating the wheel in this case has
caused and always has the posibility of creating more issues than it solves.
Extra testing and black box functionality with no standards for other
consumers of the service to follow. Yes fine if you want to use it yourself
but why then re-create something for additional dev and testing when you can
find an existing standard that fits, lets be honest you will be hard pressed
not to.

I have no idea what you're talking about. It's the use of the
..NET-specific features that may lead to "reinventing the wheel", as if
the other end-point is not a .NET application, someone will have to
reimplement the .NET protocol, in an environment where doing so it very
difficult.

Contrast that to using some broadly supported format, like a simple
null-terminated string, or even some simple XML. Even if using XML, in
most environments there will already be support for plain XML, and of
course null-terminated strings are ubiquitous. Neither requires any
sort of special support for .NET types.
To me solutions like this are badly architected and waiting to fail, mabe im
an old fart but when I see deveopers re-creating the wheel I alway qustion
the design/architecture of the system. MS has spent a lot of time developing
the remoting services in .NET and they are for the most part cross platform
in the right hands and given correct architectural choices, why would you
try to re-write this? Low level devices maybe but Software to Software?

I don't follow. In what way is .NET data serialization "for the most
part cross platform"? Are you suggesting that I can easily (for
example) write a Java or VB6 program that connects to and communicates
with a .NET program that's using remoting or WCF? How will those
programming environments represent the .NET data types embedded in the
..NET protocols?

Pete
 
G

Göran Andersson

Dan said:
thanks for the clarification. I ended up changing approaches. I never
liked the indexing method. I changed it to a queue. Now i pull the
first object from the queue and immediately put it back. then return
the object. This seemed simpler and had less "moving parts". I will
change it to use a sync object like you exampled though. I think i
remember posted about not locking "this".

public class QsServants : List<QsServant>
{
private Queue<QsServant> servantQueue = new Queue<QsServant>();
public QsServant Next()
{
QsServant q = null;
lock (this)
{
q = servantQueue.Dequeue();
servantQueue.Enqueue(q);
}
return q;
}
/// <summary>
public void Initialize()
{
this.ForEach(delegate(QsServant q) {
servantQueue.Enqueue(q); });
}
}

Yes, that works. However, it's commonly considered as bad practice to
use lock(this). You should use a private object instead, to elliminate
the possibility to cause a deadlock with code outside the class locking
on the same object.

public class QsServants : List<QsServant> {

private Queue<QsServant> _servantQueue;
private object _sync = new object();

public QsServant Next() {
QsServant q;
lock (_sync) {
q = _servantQueue.Dequeue();
_servantQueue.Enqueue(q);
}
return q;
}

public void Initialize() {
_servantQueue = new Queue<QsServant>(this);
}
}
 
T

Tom Shelton

I have TCP code that is incrementing an int for each accept socket. I tried to use lock(int) for synchronization but
that doesn't work. I have settled on declaring the int as volatile. Will that work? Based on what i read about
volatile this could work.

This is a poor man's load balancing app. The clients contact with this app and this app is just going to round-robin
through the actual doers of stuff.

using SNS = System.Net.Sockets;
private const int Initial_Buffer_Size = 65536;
private SNS.TcpListener listener = null;
//this is incremented before the execution that is why it is initialized to -1 instead of 0.
private volatile int nextServantIndex = -1;

private void DoAcceptTcpClientCallback(IAsyncResult ar)
{
try
{
SNS.TcpListener listener = (SNS.TcpListener)ar.AsyncState;
SNS.TcpClient clientSckt = listener.EndAcceptTcpClient(ar);
listener.BeginAcceptTcpClient(new AsyncCallback(DoAcceptTcpClientCallback), listener);
byte[] readbuffer = new byte[Initial_Buffer_Size];
SNS.NetworkStream ns = clientSckt.GetStream();
StringBuilder message = new StringBuilder();
int bytesread = ns.Read(readbuffer, 0, readbuffer.Length);
while (bytesread > 0)
{
message.Append(Encoding.UTF8.GetString(readbuffer, 0, bytesread));
bytesread = ns.Read(readbuffer, 0, readbuffer.Length);
}
if (message.Length > 0)
{
if (Properties.Settings.Default.RouterMode)
{
//lock the int. since this is async IO more than 1 IO could be at this point
//need to make sure that the variable only gets accessed in a serial manner.
//move to the next servant
if (++nextServantIndex >= Properties.Settings.Default.Servants.Count)
nextServantIndex = 0;


Declare value as volitile. Use
System.Threading.Interlocked.Increment/Decrment to increment/decrement your
value.

// instead of ++
Interlocked.Increment(ref nextServantIndex);

// instead of --
Interlocked.Decrement(ref nextServantIndex);
 
G

Göran Andersson

Tom said:
Declare value as volitile. Use
System.Threading.Interlocked.Increment/Decrment to increment/decrement your
value.

// instead of ++
Interlocked.Increment(ref nextServantIndex);

// instead of --
Interlocked.Decrement(ref nextServantIndex);

However, he has to increment the value, check against a limit and reset
the value if the limit is reached. The CompareExchange method could be
used if he only had to check and reset, but there is no method in the
Interlocked class that can handle all of that.
 
P

Peter Duniho

Paul said:

Sorry, I still don't follow. Your reply doesn't answer the question I
asked.

I understand .NET uses existing specifications for formatting serialized
data. But at what point does that allow someone to write a non-.NET
program that can receive .NET data types without any more effort than
using a simpler application protocol such as null-terminated strings or
plain XML?

Specifically: please show a code example where the .NET program is using
WCF, but the remote endpoint is not and yet is no more complicated than
(for example) simply receiving null-terminated strings.

Thanks,
Pete
 
P

Paul

You obviously do understand which is why you changed the goal posts.

If your saying to me WCF is not interoperable then I'm happy for you to
believe that, it really is no skin off my nose.
 
P

Peter Duniho

Paul said:
You obviously do understand which is why you changed the goal posts.

What goal posts? I readily admit that I don't understand. I've said so
several times. I certainly haven't "changed the goal posts" though...I
have been discussing the exact same end-user goal all along.
If your saying to me WCF is not interoperable then I'm happy for you to
believe that, it really is no skin off my nose.

I suppose not. But if you can't explain how WCF is interoperable in the
manner that I and Ben are describing and have been describing all along,
that strongly suggests it's actually not.

Since you are the person who originally asserted that Ben's statement
was incorrect, it's up to you to substantiate that claim, should you
care for anyone to believe it. But yes, if you don't care whether
anyone believes it, I suppose that qualifies as "no skin off [your] nose".

Pete
 
B

Ben Voigt [C++ MVP]

Paul said:
You obviously do understand which is why you changed the goal posts.

If your saying to me WCF is not interoperable then I'm happy for you to
believe that, it really is no skin off my nose.

ok, quick, consume a WCF service from VB6. How about python? perl? a
big-endian CPU?

Any solution you come up with will be (much) longer than is needed to handle
a protocol based on a simpler foundation, like pure HTTP (if your target has
built-in HTTP libraries) or TCP (if your target doesn't come with HTTP
libraries).



__________ Information from ESET NOD32 Antivirus, version of virus signature database 4512 (20091015) __________

The message was checked by ESET NOD32 Antivirus.

http://www.eset.com
 
B

Ben Voigt [C++ MVP]

Göran Andersson said:
However, he has to increment the value, check against a limit and reset
the value if the limit is reached. The CompareExchange method could be
used if he only had to check and reset, but there is no method in the
Interlocked class that can handle all of that.

I already posted a solution that does (using Interlocked.CompareExchange).



__________ Information from ESET NOD32 Antivirus, version of virus signature database 4512 (20091015) __________

The message was checked by ESET NOD32 Antivirus.

http://www.eset.com
 

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

Top