Zth (libzth)
Loading...
Searching...
No Matches
4_sync.cpp

Synchronization primitives example.

Synchronization primitives example.This program will print something like this:

fiber 1 outside of critical section
fiber 2 outside of critical section
fiber 3 outside of critical section
Other fiber
Other fiber
 { fiber 1 at start of critical section
Other fiber
Other fiber
Other fiber
 } fiber 1 at end of critical section
fiber 1 outside of critical section
Other fiber
 { fiber 2 at start of critical section
Other fiber
Other fiber
Other fiber
 } fiber 2 at end of critical section
fiber 2 outside of critical section
Other fiber
 { fiber 3 at start of critical section
Other fiber
Other fiber
Other fiber
 } fiber 3 at end of critical section
fiber 3 outside of critical section
Other fiber
 { fiber 1 at start of critical section
Other fiber
Other fiber
Other fiber
 } fiber 1 at end of critical section
fiber 1 outside of critical section
Other fiber
 { fiber 2 at start of critical section
Other fiber
Other fiber
Other fiber
 } fiber 2 at end of critical section
fiber 2 outside of critical section
Other fiber
 { fiber 3 at start of critical section
Other fiber
Other fiber
Other fiber
 } fiber 3 at end of critical section
fiber 3 outside of critical section
Other fiber
 { fiber 1 at start of critical section
Other fiber
Other fiber
Other fiber
 } fiber 1 at end of critical section
Other fiber
 { fiber 2 at start of critical section
Other fiber
Other fiber
Other fiber
 } fiber 2 at end of critical section
Other fiber
 { fiber 3 at start of critical section
Other fiber
Other fiber
Other fiber
 } fiber 3 at end of critical section
Other fiber
/*
* SPDX-FileCopyrightText: 2019-2026 Jochem Rutgers
*
* SPDX-License-Identifier: CC0-1.0
*/
#include <zth>
#include <cstdio>
// Even though all code within a fiber is executed atomically when not yielded, sometimes it is
// required to yield within a (long) critical section anyway. If you have many fibers, but only a
// few may be trying to access the critical section, it is still nice to yield. In that case,
// synchronization primitives are required. Zth offers a few, namely a mutex, signal (a.k.a.
// condition), and a semaphore. Their interface is straight-forward. Here, we only show an example
// with a mutex.
static zth::Mutex mutex;
static zth::Gate gate(4);
static void fiber(int id)
{
for(int i = 0; i < 3; i++) {
printf("fiber %d outside of critical section\n", id);
zth::Locked l(mutex);
printf(" { fiber %d at start of critical section\n", id);
// It does not matter how and how often we yield, other fibers trying to lock the
// mutex will not be scheduled, but others may.
printf(" } fiber %d at end of critical section\n", id);
}
gate.pass();
}
static bool stopOther = false;
static void otherFiber()
{
zth::currentFiber().setName("other fiber");
while(!stopOther) {
printf("Other fiber\n");
}
}
int main_fiber(int /*argc*/, char** /*argv*/)
{
zth::fiber(fiber, 1);
zth::fiber(fiber, 2);
zth::fiber(fiber, 3);
zth::fiber(otherFiber);
gate.wait();
stopOther = true;
return 0;
}
Fiber-aware barrier/gate.
Definition sync.h:1487
Mutex RAII, that locks and unlocks the mutex automatically.
Definition sync.h:566
Fiber-aware mutex.
Definition sync.h:505
void setName(string const &name)
Definition util.h:751
int main_fiber(int argc, char **argv)
Definition main.cpp:11
void outOfWork()
Force a context switch.
Definition worker.h:476
fiber_type< F >::fiber fiber(F &&f, Args &&... args)
Create and start a new fiber.
Definition async.h:1192
void yield(Fiber *preferFiber=nullptr, bool alwaysYield=false, Timestamp const &now=Timestamp::now())
Allow a context switch.
Definition worker.h:454
Fiber & currentFiber() noexcept
Return the currently executing fiber.
Definition worker.h:417
string format(char const *fmt,...)
Format like sprintf(), but save the result in an zth::string.
Definition util.h:483