Static Functions in a Multi Threaded App

S

Seenu

Is it safe to create a static function in a multi threaded application
? As an example, I have a function that logs errors ,exceptions and
some informational data
public static void Log(....)
{
//
}

There are multiple threads in this application that call this function.
Is there any advantage if each thread creates an instance of the
class(I would remove the static) and uses it ? The function itself does
not access any instance variables. Will there be any thread saefty
issues if it is static. ?

Thank You

SRLoka
 
N

Nicholas Paldino [.NET/C# MVP]

SRLoka,

It all depends on what you are doing in the function. Just because you
arent accessing fields (static or instance), doesn't mean that you won't run
into threading issues.

Your best bet would be to place the MethodImpl attribute on the method,
passing the MethodImplOptions.Synchronized value into the constructor. This
will ensure that access to the Log method is synchronized.

If you created a separate class instance on each thread, it wouldn't
necessarily work, since they might all access the same file, and you could
end up interweaving the writes to the file in between each other (if you did
multiple writes per call to Log).

Hope this helps.
 
S

Seenu

I am trying to visualize how a static function would be executed at
runtime. I can understand the problem if I use an instance and they all
access the same file. But in my case, I am logging to a database. How
would that still create threading issues ? BTW, this app runs on a
multi cpu machine.

Thanks
 
S

Samuel R. Neff

As long as the database connection is created/released from the pool
within Log() then it's thread safe. There would be no difference if
the method is static or instance based since all it's resources are
internalized.

For performance you might want to consider having Log() just push the
log items into a queue (which needs to be synchronized) and have a
background thread put them in the database asynchronously--depends on
how many log calls you're making.

HTH,

Sam
 
N

Nicholas Paldino [.NET/C# MVP]

Seenu,

Well, depending on how you are allocating the connection (do you have
one connection that you hold on a static level, or are you creating one each
time the function is iterated). Also, do you execute more than one command
in the method? These are the things you have to worry about.

Basically, if you are writing to a database, you would create your
commands and then execute them. Since everything is created on the stack
(at least the references to the objects you make), and not to static fields,
you should have no problem. I would just make sure that you wrap multiple
statements in a transaction so that it is consistent.
 
S

Seenu

For argument sake, leaving aside my requirements, say I have a
function
public static void Log(...)
{
int i=0;
Statement1;
Statement2;
i++;
....
....
StatementN
}

If on a dual cpu machine, one thread calls this function and then
another thread calls it before the procedure is completed(its possible
right ?), will variable i be a separate copy for each ? Since only one
copy of the object(function) exists, are variables still maintained
separately for each thread ? Are variables maintained on the stack per
process or per application ?
May be this is a dumb question but I am trying to understand some
internals.

Thanks
 
W

Willy Denoyette [MVP]

Seenu said:
For argument sake, leaving aside my requirements, say I have a
function
public static void Log(...)
{
int i=0;
Statement1;
Statement2;
i++;
....
....
StatementN
}

If on a dual cpu machine, one thread calls this function and then
another thread calls it before the procedure is completed(its possible
right ?), will variable i be a separate copy for each ? Since only one
copy of the object(function) exists, are variables still maintained
separately for each thread ? Are variables maintained on the stack per
process or per application ?
May be this is a dumb question but I am trying to understand some
internals.

Thanks

Yes, i is a local variable, that means it's stack allocated and as each
thread has it's own stack, each thread gets it's own private copy of i.

Willy.
 
S

Seenu

So a separate stach for each thread would mean if the static function
does not access any outside variables, it is thread safe ? Am I correct
?
 
W

Willy Denoyette [MVP]

Seenu said:
So a separate stach for each thread would mean if the static function
does not access any outside variables, it is thread safe ? Am I correct
?
No you cannot generalize this, the method in the sample you posted, is
indead thread safe because the local variable i of type int is on the
callers stack. But if a local variable holds a reference to shared state,
it's not threadsafe.

Willy.
 
W

William Stacey [MVP]

That is what I would do. As you don't want your source threads waiting for
log updates. Create your static log class. In 2.0 you can even use Static
on the class itself to get compile checks to allow only static members.
Anyway, add a queue (either a sync queue or my Bounded blocking queue on the
CodeProject) to the class. Now create a new worker thread in the Log class
that blocks on Dequeue on the queue. And put a Log.Message(strng msg)
static method that adds msg to the queue. Now the reader thread will just
keep servicing the queue or block when it is empty. Now you can keep one
connection open and send updates in sync one after another.
 

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