mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 01:06:45 +08:00
modify producer-consumer policy flag
This commit is contained in:
parent
bb21429d0d
commit
e86d3e10e1
@ -9,7 +9,7 @@ A high-performance inter-process communication using shared memory on Linux/Wind
|
||||
* 除STL外,无其他依赖
|
||||
* 无锁(lock-free)或轻量级spin-lock
|
||||
* 底层数据结构为循环数组(circular array)
|
||||
* `ipc::route`支持单生产多消费,`ipc::channel`支持多生产多消费
|
||||
* `ipc::route`支持单写多读,`ipc::channel`支持多写多读
|
||||
|
||||
## Usage
|
||||
|
||||
|
||||
@ -13,8 +13,7 @@ DESTDIR = ../output
|
||||
-Wno-attributes \
|
||||
-Wno-missing-field-initializers \
|
||||
-Wno-unused-variable \
|
||||
-Wno-unused-function \
|
||||
-Wno-class-memaccess
|
||||
-Wno-unused-function
|
||||
|
||||
INCLUDEPATH += \
|
||||
../test \
|
||||
|
||||
@ -6,7 +6,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
find_package(Qt5 COMPONENTS Core Test REQUIRED)
|
||||
|
||||
if(NOT MSVC)
|
||||
add_compile_options(-Wno-attributes -Wno-missing-field-initializers -Wno-unused-variable -Wno-unused-function -Wno-class-memaccess)
|
||||
add_compile_options(-Wno-attributes -Wno-missing-field-initializers -Wno-unused-variable -Wno-unused-function)
|
||||
endif()
|
||||
|
||||
include_directories(../../include ../../src ../../test ../../test/capo)
|
||||
|
||||
@ -44,10 +44,10 @@ enum class trans { // transmission
|
||||
// producer-consumer policy flag
|
||||
|
||||
template <relat Rp, relat Rc, trans Ts>
|
||||
struct prod_cons {};
|
||||
struct wr {};
|
||||
|
||||
// implement with multi routes
|
||||
struct prod_cons_routes {};
|
||||
struct wr_routes {};
|
||||
|
||||
// concept helpers
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ using handle_t = void*;
|
||||
using buff_t = buffer;
|
||||
|
||||
template <typename Flag>
|
||||
struct IPC_EXPORT channel_detail {
|
||||
struct IPC_EXPORT chan_impl {
|
||||
static handle_t connect (char const * name);
|
||||
static void disconnect(handle_t h);
|
||||
|
||||
@ -26,7 +26,7 @@ struct IPC_EXPORT channel_detail {
|
||||
};
|
||||
|
||||
template <>
|
||||
struct IPC_EXPORT channel_detail<prod_cons_routes> {
|
||||
struct IPC_EXPORT chan_impl<wr_routes> {
|
||||
static handle_t connect (char const * name);
|
||||
static void disconnect(handle_t h);
|
||||
|
||||
@ -38,34 +38,34 @@ struct IPC_EXPORT channel_detail<prod_cons_routes> {
|
||||
};
|
||||
|
||||
template <typename Flag>
|
||||
class channel_impl {
|
||||
class chan_wrapper {
|
||||
private:
|
||||
using detail_t = channel_detail<Flag>;
|
||||
using detail_t = chan_impl<Flag>;
|
||||
|
||||
handle_t h_ = nullptr;
|
||||
std::string n_;
|
||||
|
||||
public:
|
||||
channel_impl() = default;
|
||||
chan_wrapper() = default;
|
||||
|
||||
explicit channel_impl(char const * name) {
|
||||
explicit chan_wrapper(char const * name) {
|
||||
this->connect(name);
|
||||
}
|
||||
|
||||
channel_impl(channel_impl&& rhs) {
|
||||
chan_wrapper(chan_wrapper&& rhs) {
|
||||
swap(rhs);
|
||||
}
|
||||
|
||||
~channel_impl() {
|
||||
~chan_wrapper() {
|
||||
disconnect();
|
||||
}
|
||||
|
||||
void swap(channel_impl& rhs) {
|
||||
void swap(chan_wrapper& rhs) {
|
||||
std::swap(h_, rhs.h_);
|
||||
n_.swap(rhs.n_);
|
||||
}
|
||||
|
||||
channel_impl& operator=(channel_impl rhs) {
|
||||
chan_wrapper& operator=(chan_wrapper rhs) {
|
||||
swap(rhs);
|
||||
return *this;
|
||||
}
|
||||
@ -82,8 +82,8 @@ public:
|
||||
return (handle() != nullptr);
|
||||
}
|
||||
|
||||
channel_impl clone() const {
|
||||
return channel_impl { name() };
|
||||
chan_wrapper clone() const {
|
||||
return chan_wrapper { name() };
|
||||
}
|
||||
|
||||
bool connect(char const * name) {
|
||||
@ -109,7 +109,7 @@ public:
|
||||
}
|
||||
|
||||
static bool wait_for_recv(char const * name, std::size_t r_count) {
|
||||
return channel_impl(name).wait_for_recv(r_count);
|
||||
return chan_wrapper(name).wait_for_recv(r_count);
|
||||
}
|
||||
|
||||
bool send(void const * data, std::size_t size) {
|
||||
@ -129,6 +129,9 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Flag>
|
||||
using chan = chan_wrapper<Flag>;
|
||||
|
||||
/*
|
||||
* class route
|
||||
*
|
||||
@ -137,19 +140,19 @@ public:
|
||||
* would receive your sent messages.
|
||||
*
|
||||
* A route could only be used in 1 to N
|
||||
* (one producer/server/sender to multi consumers/clients/receivers)
|
||||
* (one producer/writer to multi consumers/readers)
|
||||
*/
|
||||
|
||||
using route = channel_impl<ipc::prod_cons<relat::single, relat::multi, trans::broadcast>>;
|
||||
using route = chan<ipc::wr<relat::single, relat::multi, trans::broadcast>>;
|
||||
|
||||
/*
|
||||
* class channel
|
||||
*
|
||||
* You could use multi producers/servers/senders for sending messages to a channel,
|
||||
* then all the consumers/clients/receivers which are receiving with this channel,
|
||||
* You could use multi producers/writers for sending messages to a channel,
|
||||
* then all the consumers/readers which are receiving with this channel,
|
||||
* would receive your sent messages.
|
||||
*/
|
||||
|
||||
using channel = channel_impl<ipc::prod_cons<relat::multi, relat::multi, trans::broadcast>>;
|
||||
using channel = chan<ipc::wr<relat::multi, relat::multi, trans::broadcast>>;
|
||||
|
||||
} // namespace ipc
|
||||
|
||||
@ -88,26 +88,26 @@ struct ch_multi_routes {
|
||||
|
||||
namespace ipc {
|
||||
|
||||
ipc::handle_t channel_detail<prod_cons_routes>::connect(char const * /*name*/) {
|
||||
ipc::handle_t chan_impl<wr_routes>::connect(char const * /*name*/) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void channel_detail<prod_cons_routes>::disconnect(ipc::handle_t /*h*/) {
|
||||
void chan_impl<wr_routes>::disconnect(ipc::handle_t /*h*/) {
|
||||
}
|
||||
|
||||
std::size_t channel_detail<prod_cons_routes>::recv_count(ipc::handle_t /*h*/) {
|
||||
std::size_t chan_impl<wr_routes>::recv_count(ipc::handle_t /*h*/) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool channel_detail<prod_cons_routes>::wait_for_recv(ipc::handle_t /*h*/, std::size_t /*r_count*/) {
|
||||
bool chan_impl<wr_routes>::wait_for_recv(ipc::handle_t /*h*/, std::size_t /*r_count*/) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool channel_detail<prod_cons_routes>::send(ipc::handle_t /*h*/, void const * /*data*/, std::size_t /*size*/) {
|
||||
bool chan_impl<wr_routes>::send(ipc::handle_t /*h*/, void const * /*data*/, std::size_t /*size*/) {
|
||||
return false;
|
||||
}
|
||||
|
||||
buff_t channel_detail<prod_cons_routes>::recv(ipc::handle_t /*h*/) {
|
||||
buff_t chan_impl<wr_routes>::recv(ipc::handle_t /*h*/) {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
22
src/ipc.cpp
22
src/ipc.cpp
@ -214,39 +214,39 @@ using policy_t = policy::choose<circ::elem_array, Flag>;
|
||||
namespace ipc {
|
||||
|
||||
template <typename Flag>
|
||||
ipc::handle_t channel_detail<Flag>::connect(char const * name) {
|
||||
ipc::handle_t chan_impl<Flag>::connect(char const * name) {
|
||||
return detail_impl<policy_t<Flag>>::connect(name);
|
||||
}
|
||||
|
||||
template <typename Flag>
|
||||
void channel_detail<Flag>::disconnect(ipc::handle_t h) {
|
||||
void chan_impl<Flag>::disconnect(ipc::handle_t h) {
|
||||
detail_impl<policy_t<Flag>>::disconnect(h);
|
||||
}
|
||||
|
||||
template <typename Flag>
|
||||
std::size_t channel_detail<Flag>::recv_count(ipc::handle_t h) {
|
||||
std::size_t chan_impl<Flag>::recv_count(ipc::handle_t h) {
|
||||
return detail_impl<policy_t<Flag>>::recv_count(h);
|
||||
}
|
||||
|
||||
template <typename Flag>
|
||||
bool channel_detail<Flag>::wait_for_recv(ipc::handle_t h, std::size_t r_count) {
|
||||
bool chan_impl<Flag>::wait_for_recv(ipc::handle_t h, std::size_t r_count) {
|
||||
return detail_impl<policy_t<Flag>>::wait_for_recv(h, r_count);
|
||||
}
|
||||
|
||||
template <typename Flag>
|
||||
bool channel_detail<Flag>::send(ipc::handle_t h, void const * data, std::size_t size) {
|
||||
bool chan_impl<Flag>::send(ipc::handle_t h, void const * data, std::size_t size) {
|
||||
return detail_impl<policy_t<Flag>>::send(h, data, size);
|
||||
}
|
||||
|
||||
template <typename Flag>
|
||||
buff_t channel_detail<Flag>::recv(ipc::handle_t h) {
|
||||
buff_t chan_impl<Flag>::recv(ipc::handle_t h) {
|
||||
return detail_impl<policy_t<Flag>>::recv(h);
|
||||
}
|
||||
|
||||
template struct channel_detail<ipc::prod_cons<relat::single, relat::single, trans::unicast >>;
|
||||
template struct channel_detail<ipc::prod_cons<relat::single, relat::multi , trans::unicast >>;
|
||||
template struct channel_detail<ipc::prod_cons<relat::multi , relat::multi , trans::unicast >>;
|
||||
template struct channel_detail<ipc::prod_cons<relat::single, relat::multi , trans::broadcast>>;
|
||||
template struct channel_detail<ipc::prod_cons<relat::multi , relat::multi , trans::broadcast>>;
|
||||
template struct chan_impl<ipc::wr<relat::single, relat::single, trans::unicast >>;
|
||||
template struct chan_impl<ipc::wr<relat::single, relat::multi , trans::unicast >>;
|
||||
template struct chan_impl<ipc::wr<relat::multi , relat::multi , trans::unicast >>;
|
||||
template struct chan_impl<ipc::wr<relat::single, relat::multi , trans::broadcast>>;
|
||||
template struct chan_impl<ipc::wr<relat::multi , relat::multi , trans::broadcast>>;
|
||||
|
||||
} // namespace ipc
|
||||
|
||||
@ -19,7 +19,7 @@ template <typename Flag>
|
||||
struct prod_cons_impl;
|
||||
|
||||
template <>
|
||||
struct prod_cons_impl<prod_cons<relat::single, relat::single, trans::unicast>> {
|
||||
struct prod_cons_impl<wr<relat::single, relat::single, trans::unicast>> {
|
||||
std::atomic<circ::u2_t> rd_; // read index
|
||||
std::atomic<circ::u2_t> wt_; // write index
|
||||
|
||||
@ -63,8 +63,8 @@ struct prod_cons_impl<prod_cons<relat::single, relat::single, trans::unicast>> {
|
||||
};
|
||||
|
||||
template <>
|
||||
struct prod_cons_impl<prod_cons<relat::single, relat::multi , trans::unicast>>
|
||||
: prod_cons_impl<prod_cons<relat::single, relat::single, trans::unicast>> {
|
||||
struct prod_cons_impl<wr<relat::single, relat::multi , trans::unicast>>
|
||||
: prod_cons_impl<wr<relat::single, relat::single, trans::unicast>> {
|
||||
|
||||
template <typename E, typename F, typename EB>
|
||||
bool pop(E* /*elems*/, circ::u2_t& /*cur*/, F&& f, EB* elem_start) {
|
||||
@ -86,8 +86,8 @@ struct prod_cons_impl<prod_cons<relat::single, relat::multi , trans::unicast>>
|
||||
};
|
||||
|
||||
template <>
|
||||
struct prod_cons_impl<prod_cons<relat::multi , relat::multi, trans::unicast>>
|
||||
: prod_cons_impl<prod_cons<relat::single, relat::multi, trans::unicast>> {
|
||||
struct prod_cons_impl<wr<relat::multi , relat::multi, trans::unicast>>
|
||||
: prod_cons_impl<wr<relat::single, relat::multi, trans::unicast>> {
|
||||
|
||||
std::atomic<circ::u2_t> ct_; // commit index
|
||||
|
||||
@ -118,7 +118,7 @@ struct prod_cons_impl<prod_cons<relat::multi , relat::multi, trans::unicast>>
|
||||
};
|
||||
|
||||
template <>
|
||||
struct prod_cons_impl<prod_cons<relat::single, relat::multi, trans::broadcast>> {
|
||||
struct prod_cons_impl<wr<relat::single, relat::multi, trans::broadcast>> {
|
||||
std::atomic<circ::u2_t> wt_; // write index
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
@ -180,8 +180,8 @@ struct prod_cons_impl<prod_cons<relat::single, relat::multi, trans::broadcast>>
|
||||
};
|
||||
|
||||
template <>
|
||||
struct prod_cons_impl<prod_cons<relat::multi , relat::multi, trans::broadcast>>
|
||||
: prod_cons_impl<prod_cons<relat::single, relat::multi, trans::broadcast>> {
|
||||
struct prod_cons_impl<wr<relat::multi , relat::multi, trans::broadcast>>
|
||||
: prod_cons_impl<wr<relat::single, relat::multi, trans::broadcast>> {
|
||||
|
||||
std::atomic<circ::u2_t> ct_; // commit index
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ struct msg_t {
|
||||
};
|
||||
|
||||
template <ipc::relat Rp, ipc::relat Rc, ipc::trans Ts>
|
||||
using pc_t = ipc::prod_cons_impl<ipc::prod_cons<Rp, Rc, Ts>>;
|
||||
using pc_t = ipc::prod_cons_impl<ipc::wr<Rp, Rc, Ts>>;
|
||||
|
||||
template <std::size_t DataSize, typename Policy>
|
||||
struct ea_t : public ipc::circ::elem_array<Policy, DataSize> {
|
||||
@ -372,7 +372,7 @@ void Unit::test_prod_cons_performance() {
|
||||
void Unit::test_queue() {
|
||||
using queue_t = ipc::queue<msg_t, ipc::policy::choose<
|
||||
ipc::circ::elem_array,
|
||||
ipc::prod_cons<ipc::relat::single, ipc::relat::multi, ipc::trans::broadcast>
|
||||
ipc::wr<ipc::relat::single, ipc::relat::multi, ipc::trans::broadcast>
|
||||
>>;
|
||||
queue_t queue;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user