简体   繁体   中英

Boost shared memory map allocator errors

I am trying to create a shared memory manager map in boost, along with a synchronization class for the map. I previously did something roughly the same with vectors and it worked fine. I get the error mentioned in the title while using maps. Am I doing this all wrong? Code in this repo

Synchronized class:

#include <iostream>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/sync/interprocess_condition.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/thread/lock_guard.hpp>

namespace node_cluster_cache {

    using namespace boost;
    using namespace boost::interprocess;
    using std::pair;
    typedef uint64_t int64;
    typedef uint32_t int32;
    typedef std::array<int32, SIZE> msg_arr;
    typedef std::array<char, ACCESS_SIZE> access_name;

    template<class T>
    class SynchronizedMap {
    public:
        typedef allocator<T, managed_shared_memory::segment_manager> allocator_type;
        typedef lock_guard<interprocess_mutex> lock;
        
    private:
        map<access_name, T, allocator_type> _map;
        mutable interprocess_mutex io_mutex;
        mutable interprocess_condition wait_condition;

    public:
        SynchronizedMap(allocator_type alloc) : _map(alloc) {};
        void insert(const access_name name, T msg_part) {
            lock _lock(io_mutex);
            _map.insert(pair<access_name, T>(name, msg_part));
        }
        int32 size() const {
            lock _lock(io_mutex);
            return _map.size();
        }
        bool empty() const {
            lock _lock(io_mutex);
            return _map.empty();
        }
        void clear() {
            lock _lock(io_mutex);
            _map.clear();
        }
        bool erase(access_name name) {
            lock _lock(io_mutex);
            return _map.erase(name);
        }
        bool erase(typename map<access_name, T>::iterator it) {
            lock _lock(io_mutex);
            return _map.erase(it);
        }
    };
};

Message structure:

struct Message {

        int64 bit_no;
        int64 pid;
        int64 part_no;
        int64 size;
        msg_arr data;

        Message() {}

        Message(int64 bn, int64 p, int64 pn, int64 s, msg_arr& d) {
            bit_no = bn;
            pid = p;
            part_no = pn;
            size = s;
            safe_copy(data, d);
        }

        Message(int64 bn, int64 p, int64 s, msg_arr& d) {
            bit_no = bn;
            pid = p;
            part_no = 0;
            size = s;
            safe_copy(data, d);
        }
    };
template<size_t N>
    static inline void safe_copy(std::array<int32, N>& dst, std::array<int32, N>& src) {
        #undef min
        std::copy_n(src.data(), std::min(src.size(), N), dst.data());
        dst.back() = 0;
    }

Create and used like:

this->shmem = new managed_shared_memory(create_only, "node_cluster_cache", SHMEM_SIZE);
this->alloc_inst = new SynchronizedMap<Message>::allocator_type(this->shmem->get_segment_manager());
this->cache_map = this->shmem->construct<SynchronizedMap<Message> >("data_vector")(*(this->alloc_inst));
msg_arr test{ 123,456,789 };
access_name name = { 't', 'e', '\0' };
int64 a = 1;
int64 b = 2;
Message c(a, b, 4, test);
this->cache_map->insert(name, c);

The error itself:

Severity    Code    Description Project File    Line    Suppression State
Error   C2664

'node_cluster_cache::SynchronizedMap<node_cluster_cache::Message>::SynchronizedMap
(const node_cluster_cache::SynchronizedMap<node_cluster_cache::Message> &)': cannot convert argument 1 from 

'boost::interprocess::allocator<T,boost::interprocess::segment_manager<CharType,MemoryAlgorithm,IndexType>>' to 'const 

node_cluster_cache::SynchronizedMap<node_cluster_cache::Message> &' node-cluster-cache
C:\boost_1_74_0\boost\interprocess\detail\named_proxy.hpp   85  

Changing allocator_type to the value pair and defining a comparator for std::array<char, ACCESS_SIZE> solved the issue.

typedef pair<const access_name, T> value_type;
typedef allocator<value_type, managed_shared_memory::segment_manager> allocator_type;
struct cmp_str {
        bool operator()(access_name a, access_name b) const {
            for (int i = 0; ; i++) {
                if (a[i] != b[i]) {
                    return a[i] < b[i] ? -1 : 1;
                }

                if (a[i] == '\0') {
                    return 0;
                }
            }
        }
    };
map<access_name, T, cmp_str, allocator_type> _map;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM