Consult complete reference documentation at cool::channel.
In concurrent and multithreaded programming, managing communication between threads efficiently and safely is a common challenge. Traditional synchronization mechanisms such as mutexes and condition variables can be error-prone, leading to race conditions, deadlocks, or performance bottlenecks.
A more modern and expressive approach is to use message-passing mechanisms,
where threads communicate by sending and receiving messages through channels.
The cool::channel
utility provides a simple and efficient way to achieve this
in C++, enabling structured communication between threads while abstracting
away low-level synchronization details.
The cool::channel
utility is designed to provide a thread-safe communication
channel that allows:
It provides a high-level abstraction similar to message-passing primitives found in languages like Go or Rust, making concurrent programming in C++ more intuitive.
#include <cool/channel.hpp>
#include <iostream>
#include <thread>
int main() {
cool::channel<int> ch; // Create an unbounded channel for integers
std::thread producer([&]() {
ch.send(42);
});
std::thread consumer([&]() {
int value;
ch.receive(value);
std::cout << "Received: " << value << std::endl;
});
producer.join();
consumer.join();
return 0;
}
A bounded channel prevents unlimited buffering, forcing the sender to wait when the buffer is full.
#include <cool/channel.hpp>
#include <iostream>
#include <thread>
int main() {
cool::channel<int> ch(2); // Channel with a buffer size of 2
std::thread producer([&]() {
ch.send(1);
ch.send(2);
std::cout << "Waiting to send 3..." << std::endl;
ch.send(3); // Blocks until a slot is available
});
std::thread consumer([&]() {
int value;
for (int i = 0; i < 3; ++i) {
ch.receive(value);
std::cout << "Received: " << value << std::endl;
}
});
producer.join();
consumer.join();
return 0;
}
If you want to avoid blocking, you can use the try_send
and try_receive
methods, which return a bool
indicating success or failure.
#include <cool/channel.hpp>
#include <iostream>
int main() {
cool::channel<int> ch(1);
if (ch.try_send(42)) {
std::cout << "Message sent successfully!" << std::endl;
} else {
std::cout << "Channel full, message not sent." << std::endl;
}
int value;
if (ch.try_receive(value)) {
std::cout << "Received: " << value << std::endl;
} else {
std::cout << "No message available." << std::endl;
}
return 0;
}
Channels can be closed, signaling that no more messages will be sent. Receivers will return false
upon trying to receive from a closed channel.
#include <cool/channel.hpp>
#include <iostream>
#include <thread>
int main() {
cool::channel<int> ch;
std::thread producer([&]() {
ch.send(100);
ch.close(); // Close the channel
});
std::thread consumer([&]() {
int value;
while (ch.receive(value)) {
std::cout << "Received: " << value << std::endl;
}
std::cout << "Channel closed." << std::endl;
});
producer.join();
consumer.join();
return 0;
}
The operator<<
and operator>>
provide a convenient way to send and receive data using stream-like syntax.
#include <cool/channel.hpp>
#include <iostream>
int main() {
cool::channel<int> ch;
std::thread consumer([&]() {
int x;
while (ch >> x) {
std::cout << "Received: " << x << std::endl;
}
});
std::thread producer([&]() {
for (int i = 0; i < 5; ++i) {
ch << i;
}
ch << cool::eod; // End of data
});
return 0;
}
ichannel
and ochannel
to Restrict Operationsichannel<T>
allows only receiving, while ochannel<T>
allows only sending.
This prevents unwanted operations on a given channel. Note that copies
refer to the same channel.
#include <cool/channel.hpp>
#include <iostream>
void consumer(cool::ichannel<int> in) {
int value;
in.receive(value);
std::cout << "Received: " << value << std::endl;
}
void producer(cool::ochannel<int> out) {
out.send(42);
}
int main() {
cool::channel<int> ch;
std::thread c(consumer, ch);
std::thread p(producer, ch);
c.join();
p.join();
return 0;
}
cool::channel
provides a safe and efficient way to communicate between threads.By using cool::channel
, developers can simplify concurrent programming in
C++, making code cleaner, safer, and easier to reason about.