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

Synchronization primitives example.

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

Other fiber
fiber 3 outside of critical section
 { fiber 3 at start of critical section
fiber 2 outside of critical section
fiber 1 outside of critical section
Other fiber
 } fiber 3 at end of critical section
 { fiber 2 at start of critical section
Other fiber
fiber 3 outside of critical section
 } fiber 2 at end of critical section
 { fiber 1 at start of critical section
Other fiber
fiber 2 outside of critical section
 } fiber 1 at end of critical section
 { fiber 3 at start of critical section
Other fiber
fiber 1 outside of critical section
 } fiber 3 at end of critical section
 { fiber 2 at start of critical section
Other fiber
fiber 3 outside of critical section
 } fiber 2 at end of critical section
 { fiber 1 at start of critical section
Other fiber
fiber 2 outside of critical section
 } fiber 1 at end of critical section
 { fiber 3 at start of critical section
Other fiber
fiber 1 outside of critical section
 } fiber 3 at end of critical section
 { fiber 2 at start of critical section
Other fiber
 } fiber 2 at end of critical section
 { fiber 1 at start of critical section
Other fiber
 } fiber 1 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;
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);
}
}
zth_fiber(fiber)
static bool stopOther = false;
void otherFiber()
{
while(!stopOther) {
printf("Other fiber\n");
}
}
zth_fiber(otherFiber)
int main_fiber(int /*argc*/, char** /*argv*/)
{
fiber_future f1 = zth_async fiber(1);
fiber_future f2 = zth_async fiber(2);
fiber_future f3 = zth_async fiber(3);
zth_async otherFiber();
f1->wait();
f2->wait();
f3->wait();
stopOther = true;
return 0;
}
Mutex RAII, that locks and unlocks the mutex automatically.
Definition sync.h:398
Fiber-aware mutex.
Definition sync.h:348
int main_fiber(int argc, char **argv)
Definition main.cpp:11
#define zth_async
Run a function as a new fiber.
Definition async.h:828
void outOfWork()
Force a context switch.
Definition worker.h:458
#define zth_fiber(...)
Prepare every given function to become a fiber by zth_async.
Definition async.h:806
void yield(Fiber *preferFiber=nullptr, bool alwaysYield=false, Timestamp const &now=Timestamp::now())
Allow a context switch.
Definition worker.h:436
fiber_type< F >::factory fiber(F f, char const *name=nullptr)
Create a new fiber.
Definition async.h:754