3

For example I have code

while (!something} {
    //waiting
}

it does wait for something, but it uses a lot of CPU. C++ have things like thread join, condition variable wait, mutex lock - which allow to wait, so it does check some condition, but it behaves like idle process - not consuming CPU time. How it is done and is there way to make while loop (or any other code) behave like this?

avi9526
  • 202
  • 1
  • 7
  • 3
    Generally, with help from the OS (and possibly some CPU specific instructions to reduce usage during spin/wait loops). – 1201ProgramAlarm Jun 15 '19 at 18:01
  • If you want to wait for "something" to become true, it's often better to have a function that is called by an event or message, or that does a wait like you mentioned. Using a message / event handler also means that for example a UI thread keeps running so your program doesn't freeze. – Dave S Jun 15 '19 at 18:05
  • 4
    You either wait specified amount of time (`std::this_thread::sleep_for`) or you wait for certain condition (`std:: condition_variable` and friends). So there're already ways to do, what you want. – Radosław Cybulski Jun 15 '19 at 18:05
  • @radosław-cybulski yes, there is tools available, but i'd like to know a bit about the way they work – avi9526 Jun 15 '19 at 18:08
  • All of the mechanisms that you've mentioned produce a system-call for the OS to take this thread out of context. Once out of context, it remains there (without spending any CPU time of course), until it gets signaled by another thread, i.e., a thread which makes (yet another) system-call for the OS to put the previous thread back into context. So while all of this is supported in the C++ STL (and maybe even by the language standard itself), the implementation of these mechanism is OS-dependent. – goodvibration Jun 15 '19 at 18:15
  • @avi9526 what you have in your question is a spinlock. Remember the Dockey from Shrek 2? "Are we there yet? - Are we there yet? - Are we there yet?.." What is the alternative that you would propose him? Just set up the alarm clock and go sleeping until someone would "interrupt" your sleep. That is what the system does with the system interrupts. – Dmitry Kuzminov Jun 15 '19 at 18:16
  • New Intel x86 CPU will have new set of instructions to perform efficiently such a wait. See [lwn.net: short wait with umwait](https://lwn.net/ml/linux-kernel/1559944837-149589-1-git-send-email-fenghua.yu@intel.com/) – Oliv Jun 15 '19 at 19:34

2 Answers2

3

You can achieve this by calling system calls that block the execution of the thread.

You don't usually call the system directly, but use a wrapper function instead, which is an abstraction over system specific details. This approach allows your program to be portable to different systems.

In fact, this is exactly what the standard functions such as std::condition_variable::wait are: an abstraction over system interface, which in this case blocks the thread. std::cin::operator>> is another example of function call that blocks the execution of the thread.

eerorika
  • 232,697
  • 12
  • 197
  • 326
2

These are features necessarily backed by the operating system.

The OS is responsible for allocating time to your processes and threads, and you require these features to control (or, rather, make requests of) that mechanism.

Your C++ standard library implementation calls platform-specific functions provided by your operating system.

There is no way to replicate that yourself without using the kind of C++ types/functions you've already listed: mutexes & timers (or without calling those OS functions yourself, like we did in the olden days!). All you can do is a spin lock, like the one you already demonstrated.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • C++20 std::atomic `.wait(value)` and `.notify_one()` / `.notify_all()` portably expose the same kind of mechanism mutexes use (e.g. Linux `futex`), so you can fall back to OS-assisted sleep/wake with portable C++ code if your algorithm using atomics detects contention. (e.g. as a corner case of a queue like when it's full or empty, even if the queue is normally lock-free when readers and writers are active.) https://en.cppreference.com/w/cpp/atomic/atomic/wait – Peter Cordes Mar 06 '23 at 11:27