Fix CPU usage on macOS wait_until. #200
Fix CPU usage on macOS wait_until. #200
Conversation
Right this is what I originally did. Doesn't that cause the loop to run at a 100% CPU speed because WNOHANG causes |
Reading the man page makes it sound like it would...but it doesn’t seem to...the alternative version (in Maybe some kind of extremely short (millisecond or even less) sleep in the The change in this PR is exactly what was being done in 1.68.0 (and possibly earlier), just enabled on macOS only. It doesn’t seem that there were any adverse effects from it being that way before the change. |
Looks like my code for the |
Here are some more details of what I'm seeing. This is the example code:
Prior to #197, on macOS, this would spawn a new process (which would take 100% of one cpu), and when the main process exited, the spawned process didn't go away (and still too 100% cpu). After #197, this would spawn a new process (which still takes 100% of one cpu), and when the main process exited, the spawned process would usually go away (though I have seen times when it appears it doesn't go away...appears to be a timing issue) With this PR, a new process is not spawned - but the original process still takes 100% of one cpu (as you mentioned). But at least you're never stuck with 100%-consuming zombie processes. Given that - I think the best approach is to avoid spawning a new process altogether and instead trying to put a well-timed sleep in this block:
It does look like putting a sleep in there will drop CPU usage drastically. Initial tests show (on my machine):
I think that 1 second is much too large. I don't know why microseconds were higher than nanoseconds...but in multiple tests those numbers were fairly reproducible (perhaps it's a function of how I'm doing the sleep or something). I would almost say that if you are spawning a new process (as Also - I'm considering removing the "Apple-specific" section. This seems like a less fragile approach for any time that Thoughts/opinions? I can update this PR with some of those, and I ask for feedback. |
579f5e2
to
bb247c7
Compare
Codecov Report
@@ Coverage Diff @@
## develop #200 +/- ##
==========================================
Coverage ? 87.02%
==========================================
Files ? 106
Lines ? 2951
Branches ? 0
==========================================
Hits ? 2568
Misses ? 383
Partials ? 0
Continue to review full report at Codecov.
|
bb247c7
to
306578b
Compare
Check if it solves #200
Hey Nathan, can you try out the current commit on the develop branch? I restructured the way |
Yes - I will try it out. It might be a bit later this week before I'm able to do so, however. |
Sorry for the long delay (got pulled off on a bunch of other stuff). I just tested this with 1.71.0, and it is still happening for the |
306578b
to
73c53e4
Compare
Related (I believe) to boostorg/process#55 With the fix from klemens-morgenstern#197, multiple processes can still at times be spawned, and they take extremely high CPU usage. This PR basically uses the same approach used for boost 1.68.0 (which was the last time wait_for seemed to work reliably) but adds a 1ms sleep to each iteration of the loop so as not to spike the CPU.
73c53e4
to
916c96e
Compare
Still happening with 1.72 (no changes to boost::process between 1.71 and 1.72) - rebased pull request onto latest develop branch. |
Hi Nathan, thanks for bearing with me here. Can you check the current develop branch? The problem with your solution is the race condition. If the waiting thread sleeps for a second another thread might wait for and reap the child. Otherwise I'd be happy to merge. |
Yeah - still having the same issues with the latest develop. However, I understand the reasoning for not wanting to merge in this PR. |
0ae9e89
to
268795f
Compare
78bddef
to
5ad5e82
Compare
Heya Nathan, I am closing this, future issues shall be at boostorg/process. The whole wait_for / wait_until was a design mistake, since posix apis just don't support it like this. |
Related (I believe) to boostorg/process#55
With the fix from #197, multiple processes can still at times be spawned, and they take extremely high CPU usage. This PR basically uses the same approach used for boost 1.68.0 (which was the last time wait_for seemed to work reliably) and guards it for macOS compilations only.