Are there C++11 critical sections?
Asked Answered
F

3

5

I'm trying to find the equivalent of a critical section for C++11 , is the new C++11 mutex concept process-bound (e.g. enforces mutex only on the user-space) ? Perhaps it's implementation specific since I cannot find anything specific on it. Perhaps C++11 have their own critical section classes as mutexes are cross-process, right? Please help.

Floaty answered 7/5, 2014 at 13:47 Comment(3)
@MichaelFoukarakis I've read other places that in general mutexes are implemented to lock across processes, whilst critical sections are process-bound and thusly only applies within the user-space.Floaty
"Critical sections" is just a fancy Microsoft word for a mutex.Unflinching
@JamesKanze A critical section is completely ring 3 (a.k.a. user mode). A mutex is a ring 0 (a.k.a. kernel mode) object and can be shared across processes. A critical section is optimum for a single process as it does not have kernel/user mode transitions. Not the same as a mutex.Halleyhalli
O
9

A standard library implementation is free to use any mutex implementation it likes that meets the requirements and behaviors set forth in the standard. An implementation that provides cross-process locking - which the standard doesn't require - would likely be less performant than one that does not. A high-quality implementation will therefore most likely provide process-local mutexes (mutices?).

So although one could bang out a conformant implementation of C++11 mutexes using, e.g., named semaphores, one would have a hard time selling that implementation to users. To my knowledge no popular implementation exists that provides cross-process locking in std::mutex.

Ophthalmia answered 7/5, 2014 at 14:2 Comment(2)
Curious. All of the mutex in Posix are cross process (at least under Solaris), and they still perform as fast as the mutex in other systems. (As for CriticalSection under Windows: this is just a Microsoft misnomer for what every one else calls a mutex.)Unflinching
@JamesKanze I thought of linux futexes immediately after writing this answer, which are also cross-process with no overhead when uncontended. I suppose instead of saying that cross-process mutexes would "likely be less performant" I actually should have said that given C++'s focus on performance first that std::mutex is likely to be cross-process on systems where it's possible with no overhead, and process-local on systems where providing cross-process locking would be more expensive.Ophthalmia
U
1

The C++ standard only concerns single programs, thus a single process; it has nothing to say about what happens outside of the process. At least under some Posix implementations, some "mutex" are cross-process, so under them, any C++ mutex will also be cross-process. Under other systems, it probably depends on the system.

Also: implementing the mutex in user space doesn't mean that it can't be cross-process, since user space can include shared memory or mmaped space, which is accessible from several processes.

Unflinching answered 7/5, 2014 at 14:15 Comment(6)
"all "mutex" are cross-process" -- what do you mean by this, in relation to the existence (and default-ness) of PTHREAD_PROCESS_PRIVATE? That some Posix implementations ignore it? Which would be valid, since a shared mutex has all the defined behaviour of a private one.Moan
@SteveJessop According to the Open Group's specification for pthread_mutexattr_getpshared, "If the process-shared attribute is PTHREAD_PROCESS_PRIVATE, the mutex shall only be operated upon by threads created within the same process as the thread that initialized the mutex; if threads of differing processes attempt to operate on such a mutex, the behavior is undefined." So a conforming implementation could have all mutexes shared.Ophthalmia
@SteveJessop Actually, I don't know. I don't remember having seen it in the documentation, so I never used it. What I do remember is that I didn't have to do anything special for the mutex to work between processes; just create it somewhere where both processes could see it.Unflinching
@Casey: right. Together with what James says in his later comment, I suspect his code is unintentionally non-Posix-portable. That is to say it works on some Posix implementations but not others. Of course if other parts of the code are intentionally non-portable for other reasons then this isn't a problem :-)Moan
@SteveJessop I don't remember seeing anything about this option in the Solaris documentation at the time, so I don't know. We were told that we didn't have to worry about anything but Solaris, and we programmed against the Solaris documentation, rather than Posix. Some of the applications have since been ported to Linux, but I don't know if the one using shared Mutex was one of them, and even if it was, I don't know if they needed to change it.Unflinching
@SteveJessop Anyway, I was basing my statement on personal experience with one particular implementation, once upon a time. I've edited my statement to change "all" to "some", but at least one implementation, at one time, did support shared mutexes, and our profiles indicated that they weren't any slower than mutexes which were only accessed from one process. (Depending on how the system implements threads, processes and mutexes, it could just fall out naturally that way. Or be almost impossible.)Unflinching
B
0

You can implement it like this:

  static void fn()
  {
      static std::mutex criticalSection;
      std::lock_guard<std::mutex> lockMySection(criticalSection);

      // now safely in a "critical section"
  }
Bough answered 30/10 at 3:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.