Repository navigation
Volatile vs Interlocked vs lock in C#: .NET 10 and a harness that races - #2276
Open
vladimir-pecanac-main wants to merge 2 commits into
Open
vladimir-pecanac-main wants to merge 2 commits into
vladimir-pecanac-main wants to merge 2 commits into
Conversation
…type, Exchange and CompareExchange examples
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Updates the sample for the article "Volatile vs Interlocked vs lock in C#" (https://code-maze.com/csharp-volatile-interlocked-lock/). Only
csharp-advanced-topics/VolatileInterlockedLockInCsharpchanges.AccountService.WithdrawBalancenow runs ten workers doing one hundred withdrawals each (the same 1,000 withdrawals of 100 from 100,000) instead of 1,000 one-shot tasks that each slept a random 50 to 300 ms. The sleep spread the tasks out so far that the race rarely happened and the unsynchronized and volatile runs often printed the correct 0. On the new harness, ten consecutive runs on .NET 10.0.10 never printed 0 unsynchronized or under volatile, and lock and Interlocked printed 0 in all ten. The test suite drops from about 40 seconds to well under a second.private object _lock = new object();becomesprivate readonly Lock _lock = new();(System.Threading.Lock, .NET 9 and later).Account.WithdrawIfSufficient(an Interlocked.CompareExchange retry loop that never overdraws) and a newOneShotInitializer(Interlocked.Exchange as a one-shot gate), both demonstrated in Program.cs and covered by a test.NotEqual(100000, ...)andNotEqual(1000, ...), which can never fail. Asserting that the race happened would be flaky, because a race is not guaranteed to occur, so they are renamed to...ThenFinalBalanceIsNotGuaranteedand assert the invariant that always holds: the balance stays between 0 and 100,000.Build: 0 warnings, 0 errors. Tests: 6 of 6 passing.
dotnet list package --vulnerable --include-transitive: no vulnerable packages. SDK 10.0.302, runtime 10.0.10.