This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

177
cppdraft/thread/latch.md Normal file
View File

@@ -0,0 +1,177 @@
[thread.latch]
# 32 Concurrency support library [[thread]](./#thread)
## 32.9 Coordination types [[thread.coord]](thread.coord#thread.latch)
### 32.9.2 Latches [thread.latch]
#### [32.9.2.1](#general) General [[thread.latch.general]](thread.latch.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10677)
A latch is a thread coordination mechanism
that allows any number of threads to block
until an expected number of threads arrive at the latch
(via the count_down function)[.](#general-1.sentence-1)
The expected count is set when the latch is created[.](#general-1.sentence-2)
An individual latch is a single-use object;
once the expected count has been reached, the latch cannot be reused[.](#general-1.sentence-3)
#### [32.9.2.2](#latch.syn) Header <latch> synopsis [[latch.syn]](latch.syn)
[🔗](#header:%3clatch%3e)
namespace std {class latch;}
#### [32.9.2.3](#class) Class latch [[thread.latch.class]](thread.latch.class)
namespace std {class latch {public:static constexpr ptrdiff_t max() noexcept; constexpr explicit latch(ptrdiff_t expected); ~latch();
latch(const latch&) = delete;
latch& operator=(const latch&) = delete; void count_down(ptrdiff_t update = 1); bool try_wait() const noexcept; void wait() const; void arrive_and_wait(ptrdiff_t update = 1); private: ptrdiff_t counter; // *exposition only*};}
[1](#class-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10720)
A latch maintains an internal counter
that is initialized when the latch is created[.](#class-1.sentence-1)
Threads can block on the latch object,
waiting for counter to be decremented to zero[.](#class-1.sentence-2)
[2](#class-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10726)
Concurrent invocations of the member functions of latch,
other than its destructor, do not introduce data races[.](#class-2.sentence-1)
[🔗](#lib:max,latch)
`static constexpr ptrdiff_t max() noexcept;
`
[3](#class-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10736)
*Returns*: The maximum value of counter that the implementation supports[.](#class-3.sentence-1)
[🔗](#lib:latch,constructor)
`constexpr explicit latch(ptrdiff_t expected);
`
[4](#class-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10747)
*Preconditions*: expected >= 0 is true andexpected <= max() is true[.](#class-4.sentence-1)
[5](#class-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10752)
*Effects*: Initializes counter with expected[.](#class-5.sentence-1)
[6](#class-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10756)
*Throws*: Nothing[.](#class-6.sentence-1)
[🔗](#lib:count_down,latch)
`void count_down(ptrdiff_t update = 1);
`
[7](#class-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10767)
*Preconditions*: update >= 0 is true, andupdate <= counter is true[.](#class-7.sentence-1)
[8](#class-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10772)
*Effects*: Atomically decrements counter by update[.](#class-8.sentence-1)
If counter is equal to zero,
unblocks all threads blocked on *this[.](#class-8.sentence-2)
[9](#class-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10778)
*Synchronization*: Strongly happens before the returns from all calls that are unblocked[.](#class-9.sentence-1)
[10](#class-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10782)
*Throws*: system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#class-10.sentence-1)
[11](#class-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10786)
*Error conditions*: Any of the error conditions
allowed for mutex types ([[thread.mutex.requirements.mutex]](thread.mutex.requirements.mutex "32.6.4.2Mutex types"))[.](#class-11.sentence-1)
[🔗](#lib:try_wait,latch)
`bool try_wait() const noexcept;
`
[12](#class-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10798)
*Returns*: With very low probability false[.](#class-12.sentence-1)
Otherwise counter == 0[.](#class-12.sentence-2)
[🔗](#lib:wait,latch)
`void wait() const;
`
[13](#class-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10809)
*Effects*: If counter equals zero, returns immediately[.](#class-13.sentence-1)
Otherwise, blocks on *this until a call to count_down that decrements counter to zero[.](#class-13.sentence-2)
[14](#class-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10816)
*Throws*: system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2Exceptions"))[.](#class-14.sentence-1)
[15](#class-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10820)
*Error conditions*: Any of the error conditions
allowed for mutex types ([[thread.mutex.requirements.mutex]](thread.mutex.requirements.mutex "32.6.4.2Mutex types"))[.](#class-15.sentence-1)
[🔗](#lib:arrive_and_wait,latch)
`void arrive_and_wait(ptrdiff_t update = 1);
`
[16](#class-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L10832)
*Effects*: Equivalent to:count_down(update);
wait();