Joshua Joshua - 2 months ago 7
C++ Question

In C++, is there a way to lock the object itself?

I have a stl map which I would like to be synchronized across several threads. Currently I have...

Function A (Modifies map)

void Modify(std::string value)
{
pthread_mutex_lock(&map_mutex);

my_map[value] = value;

pthread_mutex_unlock(&map_mutex);
}


Function B (Reads map)

std::string Read(std::string key)
{
std::string value;

pthread_mutex_lock(&map_mutex);

std::map<std::string, std::string>::iterator it = my_map.find(key);

pthread_mutex_unlock(&map_mutex);

if(it != my_map.end())
{
return it->second;
}
else
{
return "DNE";
}
}


This is synchronized across all threads, due to the mutex. However, I have to lock the mutex in Function B even though it is not modifying the map at all. Is there a way to lock the my_map object itself in function A, and not lock it in function B while keeping thread synchronization. This way, all instances/calls of Function B continue to run freely, so long as Function A is not being run?

Thanks

Answer

You don't just want to lock the container, you also want to lock accesses into the container i.e. any iterators or pointers into it. You need to move those accesses into the locked region of the code.

std::string Read(std::string key)
{
    std::string value = "DNE";

    pthread_mutex_lock(&map_mutex);

    std::map<std::string, std::string>::iterator it = my_map.find(key);
    if(it != my_map.end())
    {
        value = it->second;
    }

    pthread_mutex_unlock(&map_mutex);

    return value;
}

There's really no practical way to do this from inside the object itself.

Comments