-
Notifications
You must be signed in to change notification settings - Fork 3
Examples Multithread
Eduard Mishkurov edited this page May 3, 2026
·
7 revisions
This example shows how logme can be used from multiple threads.
- Creating a dedicated channel per worker thread
- Using
LogmeThreadChannel(...)to route channel-less logs - Logging with
ChannelPtrin a multi-threaded program - A simple throughput-style loop
-
ChannelPtravoids channel lookup and is usually preferable on hot paths. - A per-thread default channel is convenient when library code does not receive a channel explicitly.
2026-05-03 10:33:57:467 Worker(): worker=0 msg=0
2026-05-03 10:33:57:467 Worker(): worker=1 msg=0
2026-05-03 10:33:57:467 Worker(): worker=2 msg=0
2026-05-03 10:33:57:467 Worker(): worker=2 msg=1
2026-05-03 10:33:57:467 Worker(): worker=2 msg=2
2026-05-03 10:33:57:467 Worker(): worker=2 msg=3
2026-05-03 10:33:57:467 Worker(): worker=2 msg=4
2026-05-03 10:33:57:467 Worker(): worker=2 msg=5
2026-05-03 10:33:57:467 Worker(): worker=2 msg=6
2026-05-03 10:33:57:467 Worker(): worker=2 msg=7
2026-05-03 10:33:57:467 Worker(): worker=0 msg=1
2026-05-03 10:33:57:467 Worker(): worker=1 msg=1
2026-05-03 10:33:57:467 Worker(): worker=1 msg=2
2026-05-03 10:33:57:467 Worker(): worker=0 msg=2
2026-05-03 10:33:57:467 Worker(): worker=0 msg=3
2026-05-03 10:33:57:467 Worker(): worker=3 msg=0
2026-05-03 10:33:57:467 Worker(): worker=1 msg=3
2026-05-03 10:33:57:467 Worker(): worker=2 msg=8
2026-05-03 10:33:57:467 Worker(): worker=2 msg=9
2026-05-03 10:33:57:467 Worker(): worker=2 msg=10
2026-05-03 10:33:57:467 Worker(): worker=2 msg=11
2026-05-03 10:33:57:467 Worker(): worker=2 msg=12
2026-05-03 10:33:57:467 Worker(): worker=2 msg=13
2026-05-03 10:33:57:467 Worker(): worker=2 msg=14
2026-05-03 10:33:57:467 Worker(): worker=2 msg=15
2026-05-03 10:33:57:467 Worker(): worker=2 msg=16
2026-05-03 10:33:57:467 Worker(): worker=2 msg=17
2026-05-03 10:33:57:467 Worker(): worker=2 msg=18
2026-05-03 10:33:57:467 Worker(): worker=2 msg=19
2026-05-03 10:33:57:467 Worker(): worker=2 msg=20
... output truncated, 3971 lines omitted ...
Repository folder: examples/Multithread
#include <Logme/Logme.h>
#include <atomic>
#include <chrono>
#include <thread>
#include <vector>
#if defined(_MSC_VER)
#pragma warning(disable: 4840)
#endif
static void Worker(Logme::ChannelPtr ch, int workerId, int messages, std::atomic<int>& counter)
{
// Set default thread channel so channel-less logs in this thread go to 'ch'.
LogmeThreadChannel(ch->GetID());
for (int i = 0; i < messages; i++)
{
// ChannelPtr is slightly faster than ID in multithreaded systems.
LogmeI(ch, "worker=%d msg=%d", workerId, i);
// This call does not specify a channel, but will still go to 'ch' because of LogmeThreadChannel above.
LogmeD("worker=%d (default thread channel)", workerId);
counter.fetch_add(1, std::memory_order_relaxed);
}
}
int main()
{
const int threads = 4;
const int messagesPerThread = 1000;
std::atomic<int> counter{0};
auto t0 = std::chrono::steady_clock::now();
std::vector<std::thread> workers;
workers.reserve(threads);
for (int i = 0; i < threads; i++)
{
// Create a dedicated channel for each thread.
// Using separate channels reduces contention because no name lookup is required.
auto ch = Logme::Instance->CreateChannel();
ch->AddLink(::CH);
workers.emplace_back(Worker, ch, i, messagesPerThread, std::ref(counter));
}
for (auto& t : workers)
{
t.join();
}
auto t1 = std::chrono::steady_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0).count();
LogmeI("threads=%d messages=%d time_ms=%lld",
threads,
counter.load(std::memory_order_relaxed),
(long long)ms
);
return 0;
}logme — flexible runtime logging system
Home · Getting Started · Architecture · Output · Backends · Configuration
GitHub: https://github.com/efmsoft/logme
- Home
- Getting Started
- Why logme?
- Core Concepts
- Logging Macros
- Fatal Handling
- Crash Logging
- glog Compatibility
- C API
- Choosing Logging Macros
- Function tracing
- Trace Points
- Override Scopes
- Advanced Features
- Collapse Logging
- Feature Map
- Overview
- Console Backend
- Debugger Backend
- File Backend
- File Rotation & Retention
- Buffer Backend
- Ring Buffer Backend
- SharedFile Backend
- Callback Backend
- Windows Event Log Backend
- Custom Backends
- Runtime Control
- Configuration
- Configuration JSON
- Control Server
- Environment Control
- Control Policies
- Trace Points
- Message Filtering