0

I am new to c++ coding and have a need to swap/replace the old multimap object with the newly built multimap object, as this object will be cache I would like to replace the existing object only after building the new object and just replace the object itself. This will be used in a multithreaded environment, so using the atomic load. As described in this thread Want an efficient way to swap two pointers in C++. I wrote this code

#include<iostream>
#include<map>
#include<atomic>
#include<string>
using namespace std;

// MultiMap Object
struct mmap{
multimap<string,int> stringTointmap;
};

// Structure to swap two instances of multimap
struct swapMap{
  mmap* m1;
  mmap* m2;
};

int main(){

//create Two Objects
mmap* old = new mmap();
mmap* new2= new mmap();

// populate first object
old->stringTointmap.insert(make_pair("old",1));
//populate second object
new2->stringTointmap.insert(make_pair("new1",2));

//swap two objects
atomic<swapMap> swap;
auto refresh=swap.load();
refresh= {swap.m2,swap.m1};
}

But I'm getting this error

error: expected expression
refresh= {swap.m2,swap.m1};

definitely, I'm missing something, could someone please help?

user4581301
  • 33,082
  • 7
  • 33
  • 54
Raj
  • 401
  • 6
  • 20
  • If you're new and are working on a new project, you should consider using at least C++11 and `shared_ptr<>()`... That way you're much more likely to avoid memory leaks. – Alexis Wilke May 11 '19 at 00:28
  • Why do you need to swap two objects? Don't you just need the new object to replace the old object? You don't need the old object to replace the new object, do you? (It sounds like an atomic shared_ptr would be perfect for this job.) – David Schwartz May 11 '19 at 00:31
  • @DavidSchwartz Yes you're correct, I want to replace the old object with the new one in a thread-safe manner – Raj May 11 '19 at 00:38
  • @Raj Then just use an [atomic std::shared_ptr](https://en.cppreference.com/w/cpp/memory/shared_ptr/atomic2). :) – David Schwartz May 11 '19 at 00:42
  • @DavidSchwartz I did this, atomic > old = new mmap(); mmap* new2= new mmap(); old->stringTointmap.insert(make_pair("old",1)); new2->stringTointmap.insert(make_pair("new1",2)); old.exchange(new2); now getting " _Atomic cannot be applied to type 'std::__1::shared_ptr' which is not trivially copyable" – Raj May 11 '19 at 00:53
  • Doing `shared_ptr` pretty much defeats the point of the shared_ptr. Use `shared_ptr`. – David Schwartz May 11 '19 at 01:04
  • @DavidSchwartz Tried it no luck I still get the same error. – Raj May 11 '19 at 01:09
  • See my sample code below. – David Schwartz May 11 '19 at 01:31
  • `mmap` is the name of a *nix function. You probably don't want to use that. – curiousguy May 11 '19 at 04:58

1 Answers1

1

Here's example code showing how to use atomic operations on a std::shared_ptr to do it.

#include <memory>
#include <thread>
#include <chrono>
#include <atomic>
#include <iostream>

std::shared_ptr<std::string> the_string;

int main()
{
    std::atomic_store(&the_string, std::make_shared<std::string>("first string"));

    std::thread thread(
        [&](){
            for (int i = 0; i < 5; ++i)
            {
                {
                    // pin the current instance in memory so we can access it
                    std::shared_ptr<std::string> s = std::atomic_load(&the_string);

                    // access it
                    std::cout << *s << std::endl;
                }
                std::this_thread::sleep_for(std::chrono::seconds(1));
            }
        });

    std::this_thread::sleep_for(std::chrono::seconds(2));

    // replace the current instance with a new instance allowing the old instance
    // to be removed when all threads are done with it
    std::atomic_store (&the_string, std::make_shared<std::string>("second string"));

    thread.join();
}

Output:

first string
first string
second string
second string
second string

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • Thaks for the response, I tried this with the multimap object like this shared_ptr > stringTointmap; multimap m1; m1.insert(make_pair("1",1)); atomic_store(&stringTointmap,make_shared >(m1)); this gives me an error no matching function for call to 'atomic_store', I think I'm not passing the actual object in a right way to atomic_store – Raj May 13 '19 at 20:36
  • I tried your code as is, I still get the same error no matching function for call to 'atomic_store' candidate template ignored: could not match 'atomic' against 'shared_ptr' – Raj May 13 '19 at 21:15
  • I have this in my classpath /usr/include/c++/4.2.1/ – Raj May 13 '19 at 21:48