Net threads and Windows OS file system

K

klem s

1)
* I know almost nothing about how OS operates, but I read that file
system on Windows OS is thread safe. Does that mean that while thread
is reading from a particular file, OS won’t allow any other threads
to write to that file until the first thread is finished reading from
it?

* If so, wouldn’t that imply that we should put lock around code
accessing a file only when it is imperative that particular thread
should process that file before some other thread? Thus, lock on code
accessing a file should only be used when the order in which threads
access the file is important?

* But if we don’t care in what order threads access that file, but
instead our only concern is that whichever thread is first to access
the file won’t get interrupted in the middle of processing the file by
some other thread ( which would then proceed to read/write to that
file before the first one is finished ), then we don’t have to put
locks around that code, since OS takes care of synchronization?!



2)
a) I assume FileStream instances are not thread safe?


b) This question probably won’t make much sense, but anyways …I know
that’s not the case, but would Net having some kind of monitoring
system, which would make FileStream instances accessing the same file
thread safe with respect to each other ( thus if thread 1 was
accessing file via Filestream_1.Write, then if thread 2 would try to
access same file via FileStream_2.Write, Net would put
FileStream_2.Write “on hold” until FileStream_1.Write was finished ),
be a bad idea?

In other words, how would this limit the functionality of FileStream
instances compared to functionality they have now?



Thank you
 
A

Arne Vajhøj

1)
* I know almost nothing about how OS operates, but I read that file
system on Windows OS is thread safe. Does that mean that while thread
is reading from a particular file, OS won’t allow any other threads
to write to that file until the first thread is finished reading from
it?

That depends on how the file is opened.
* If so, wouldn’t that imply that we should put lock around code
accessing a file only when it is imperative that particular thread
should process that file before some other thread? Thus, lock on code
accessing a file should only be used when the order in which threads
access the file is important?

If the file is locked at the OS level, then another access attempt
will not block but throw an exception.

Big difference.
* But if we don’t care in what order threads access that file, but
instead our only concern is that whichever thread is first to access
the file won’t get interrupted in the middle of processing the file by
some other thread ( which would then proceed to read/write to that
file before the first one is finished ), then we don’t have to put
locks around that code, since OS takes care of synchronization?!

See above.
2)
a) I assume FileStream instances are not thread safe?

I don't think it is.

Note that my comments above is about different FileStream objects
in each thread.
b) This question probably won’t make much sense, but anyways …I know
that’s not the case, but would Net having some kind of monitoring
system, which would make FileStream instances accessing the same file
thread safe with respect to each other ( thus if thread 1 was
accessing file via Filestream_1.Write, then if thread 2 would try to
access same file via FileStream_2.Write, Net would put
FileStream_2.Write “on hold” until FileStream_1.Write was finished ),
be a bad idea?

In other words, how would this limit the functionality of FileStream
instances compared to functionality they have now?

I think you will nee to do traditional locking for that.

Arne
 
K

klem s

There's no need to assume.  The documentation always tells you.  The
System.IO.FileStream class includes the MSDN boilerplate at the bottom
for classes that haven't been explicitly made thread-safe:

     Any public static (Shared in Visual Basic) members of this
     type are thread safe. Any instance members are not guaranteed
     to be thread safe.
So Stream.Synchronized is supposed to be thread safe, since wrapping a
stream inside Stream.Synchronized restricts access to it from multiple
threads.

* am I correct in assuming that for Stream.Synchronized to actually
ensure thread safety, other threads must also access that stream
through Stream.Synchronized? Thus, if other threads access stream
object directly, then they effectively bypass thread-safety mechanism?

* assuming several threads try to access same stream through
Stream.Synchronized, how does thread currently doing the reading/
writing to a stream “signal” that it is finished and thus some other
thread should be allowed an access to a stream?

In reality, there are _some_ things you can do with a FileStream object
that would in fact be thread-safe, by virtue of the underlying OS API
being thread-safe.  But, FileStream is a managed object and has managed
logic and data in it in addition to the use of the underlying unmanaged
API.  And that managed aspect hasn't been made thread-safe.  It is best
to simply treat the entire class as not thread-safe.
Should FileStream.Synchronized also be treated as non thread safe?
It's important to understand that the thread-safety that MSDN is talking
about when it describes FileStream is with respect to that one object.
Using the correct flags when opening the FileStream object, you can open
a file in a way that allows for multiple FileStream objects referring to
the same file to be created at the same time.
You mean via Fileshare enumeration? But then we could claim that
FileStream instances are in a way thread safe with respect to each
other ( assuming we set their FileShare flags appropriately )?!

I don't see how _adding_ a feature would _limit_ functionality.  That
seems counter-intuitive to me.  New features should improve the
usefulness of something and add to its functionality, rather than limit it.
If a feature doesn’t allow something, then that something can’t be
done – thus we lose the ability to do that something … and you can
quote me on that :D

thank you
 
A

Arne Vajhøj

So Stream.Synchronized is supposed to be thread safe, since wrapping a
stream inside Stream.Synchronized restricts access to it from multiple
threads.

* am I correct in assuming that for Stream.Synchronized to actually
ensure thread safety, other threads must also access that stream
through Stream.Synchronized? Thus, if other threads access stream
object directly, then they effectively bypass thread-safety mechanism?
Yes.

* assuming several threads try to access same stream through
Stream.Synchronized, how does thread currently doing the reading/
writing to a stream “signal” that it is finished and thus some other
thread should be allowed an access to a stream?

It doesn't.

The synchronized part is only for single calls, so each
thread will complete their Write call before the others
can execute their Write.

Arne
 
A

Arne Vajhøj

It doesn't.

The synchronized part is only for single calls, so each
thread will complete their Write call before the others
can execute their Write.

It simply returns a SyncStream instance and that class
have methods like:

public override void Write(byte[] bytes, int offset, int count)
{
lock (this._stream)
{
this._stream.Write(bytes, offset, count);
}
}

Arne
 
K

klem s

It doesn't.

The synchronized part is only for single calls, so each
thread will complete their Write call before the others
can execute their Write.
Uhm, so Stream.Synchronized isn’t of much use if I want particular
thread to make several Write operations without being interrupted by
other threads?!

No. The Stream.Synchronized() method is a static method, and the
documentation clearly states that static members are thread-safe.
Whether that's helpful or not depends on what you're trying to do. The
thread-safety of the method relates to being able to call the method
without explicit synchronization from multiple threads at once.

But, does that matter? Having two different synchronized wrappers for a
Stream object doesn't help you access the Stream object in a thread-safe
way. You have to always use the same synchronized wrapper across all
threads, otherwise they aren't being synchronized.
I assume you mean if each thread calls Stream.Synchronized() on object
O, then these threads still won’t be synchronized, since each call to
Stream.Synchronized() returns a reference to different wrapper? Thus,
for these threads to be synchronized, just one of the threads needs to
call Stream.Synchronized and then somehow pass the reference to the
wrapper ( returned by the call to Stream.Synchronized ) to other
threads?

But the following code snippet ( posted by Arne ) suggests that
threads will be synchronized even when each thread acquires its very
own wrapper instance on object, since different wrapper instances on O
appear to lock on same token:

public override void Write(byte[] bytes, int offset, int count)
{
lock (this._stream)
{
this._stream.Write(bytes, offset, count);
}
}

You _can_ use the Stream.Synchronized() method to wrap multiple streams
from multiple threads without worrying about some kind of conflict. So
if that's the scenario of concern, then the method's thread-safety is
helpful.
I don’t understand what you’re trying to convey here. As you’ve noted
above, we have to use same wrapper on same Stream object in order for
threads to be synchronized?!
 
K

klem s

It doesn't.

The synchronized part is only for single calls, so each
thread will complete their Write call before the others
can execute their Write.
Uhm, so Stream.Synchronized isn’t of much use if I want particular
thread to make several Write operations without being interrupted by
other threads?!

No. The Stream.Synchronized() method is a static method, and the
documentation clearly states that static members are thread-safe.
Whether that's helpful or not depends on what you're trying to do. The
thread-safety of the method relates to being able to call the method
without explicit synchronization from multiple threads at once.

But, does that matter? Having two different synchronized wrappers for a
Stream object doesn't help you access the Stream object in a thread-safe
way. You have to always use the same synchronized wrapper across all
threads, otherwise they aren't being synchronized.
I assume you mean if each thread calls Stream.Synchronized() on object
O, then these threads still won’t be synchronized, since each call to
Stream.Synchronized() returns a reference to different wrapper? Thus,
for these threads to be synchronized, just one of the threads needs to
call Stream.Synchronized and then somehow pass the reference to the
wrapper ( returned by the call to Stream.Synchronized ) to other
threads?

But the following code snippet ( posted by Arne ) suggests that
threads will be synchronized even when each thread acquires its very
own wrapper instance on object, since different wrapper instances on O
appear to lock on same token:

public override void Write(byte[] bytes, int offset, int count)
{
lock (this._stream)
{
this._stream.Write(bytes, offset, count);
}
}

You _can_ use the Stream.Synchronized() method to wrap multiple streams
from multiple threads without worrying about some kind of conflict. So
if that's the scenario of concern, then the method's thread-safety is
helpful.
I don’t understand what you’re trying to convey here? Namelly, above
you've noted that we have to use same wrapper on same Stream object in
order for threads to be synchronized?!
 
A

Arne Vajhøj

Uhm, so Stream.Synchronized isn’t of much use if I want particular
thread to make several Write operations without being interrupted by
other threads?!

Correct.

Then you need to do some synchronization yourself.

Which it very often the case in real world examples.

Arne
 
K

klem s

klem s wrote:
 Likewise, you might have multiple threads
all initializing thread-safe wrappers for different Stream instances;
they can safely do this, because the static Stream.Synchronized() method
is in fact thread-safe.
I know Stream.Synchronized creates a thread-safe (synchronized)
wrapper around the stream. But are you implying that
Stream.Synchronized itself is also thread safe? Why would a call to
Stream.Synchronized need to be synchronized?
 

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