What is the level of thread locks? What level should they be at?

Visual Studio fread "blocks other threads." There is an alternative version of _fread_nolock that reads “without blocking other threads”, which should be used only “in thread-safe contexts, such as single-threaded applications or where the call area already processes thread isolation”.

Even after reading the other several important discussions on these two issues, I am confused if the implementation of the blocking fread is on a specific FILE structure, a specific actual file, or on all fread calls on completely different files.

If you are using nolock versions, what level of lock do you need to provide? Can multiple threads read separate files in parallel without blocking? Can multiple threads write separate files in parallel without blocking? Or are there global or static variables that would be corrupted?

So, using nolock versions, you can potentially achieve better I / O bandwidth (if you don't need to move the heads, for example, when reading individual disks or an SSD), or this is a potential gain by simply reducing redundant locks to one lock (which should be negligible.)

Does VS 'ifstream.read function the same as regular fread? (I do not see its night version.)

+5
source share
2 answers

The MS standard library implementation fully supports multithreading. The C ++ standard explains this requirement:

27.2.3: Parallel access to a stream object, stream buffer object, or C-library stream by multiple streams may result in data being received unless otherwise specified.

If one thread makes a call to library a, which writes the value to the stream and, as a result, another thread reads this value from the stream through a call to library b so that it does not lead to a race, while the record is synchronized with the read bs.

This means that if you are writing a stream, blocking (not blocking files, but blocking access to the stream's data structure in memory at the same time) is done to make sure that concurrency is well managed for all other streams that use the same stream.

These blocking overheads are always present, even if they are not needed. This may have a performance aspect, according to Microsoft:

multithreaded library performance has been improved along with the performance of a once-deleted version of the library. In situations where even higher performance requires several new features.

This is why _nolock functions are provided. They directly access the stream without blocking the stream. It should be used with extreme caution, for example:

  • if your application is single-threaded (another process using one thread has its own data structure, and the OS is concurrency here)
  • if you are sure that none of the two streams uses the same stream (for example, if you have only one stream of readers, and recording is performed outside of your program).
  • if you have another synchronization mechanism that protects a critical section of your code. For example, if you use a mutex lock or a lock without lock algorithm that uses atomics.

In such cases, an additional lock to access the stream is not needed / redundant. For file intensive functions, it might be worth using no_lock.

Note: as you pointed out: it is worth using nolock for intensive access to files, where you make millions of hits.

+3
source

fread_no_lock () seems to be used after you make sure the file is locked using an external mechanism (perhaps in some form of mutex), and then you use it to reduce overhead: related: What is the intentional use of _fread_nolock, _fseek_nolock?

It may also answer any additional questions that may arise: it may or may not be possible for your hard drive to actually perform more I / O at the same time, depending on what type of hard drive you have: https://superuser.com/questions/252959/which-is-faster-copying-everything-at-once-or-one-thing-at-a-time

0
source

All Articles