I have a decode
function that decodes a string and internally uses a map to store already-decoded values for efficiency. This function is accessed by multiple threads (using pthread
), so to prevent concurrent access issues with the map, I added a std::mutex
. However, after adding the mutex, I noticed that some threads eventually stop working or appear to get stuck. When I removed the mutex locks, all threads ran without any issues.
My question is: Could this be a case of starvation? How can I resolve this?
Additional Context: This C++ code is being used in an Android application via JNI.
std::unordered_map<std::string, std::pair<int, std::vector<uint8_t>>> decoded_map;
std::mutex decoded_map_mutex;
const char* decode(const char* encodedString) {
std::string encoded(encodedString);
std::string decoded;
for (/* some condition */) {
{
std::lock_guard<std::mutex> lock(decoded_map_mutex);
// Operation involving map search
auto it = decoded_map.find(part);
if (it != decoded_map.end()) {
// Some processing
}
}
// Additional processing
{
std::lock_guard<std::mutex> lock(decoded_map_mutex);
decoded_map[part] = std::make_pair(index / 4, bytes);
}
decode += part;
}
return strdup(decoded.c_str());
}
Do not call fork
from a program that has more than one live thread. The Android OS is based on the Linux kernel, and the man 2 fork
page from Linux says this:
• The child process is created with a single thread—the one that
called fork(). The entire virtual address space of the parent
is replicated in the child, including the states of mutexes,
condition variables, and other pthreads objects; the use of
pthread_atfork(3) may be helpful for dealing with problems
that this can cause.
• After a fork() in a multithreaded program, the child can
safely call only async-signal-safe functions (see
signal-safety(7)) until such time as it calls execve(2).
All of the threads except the one that called fork
will vanish from the child process. If any of them had a mutex locked, then that mutex will stay locked, with no way to unlock it. If any of them had work-in-progress, that work will be unfinished, with no way (in general) for you to know how much of it was done.
You asked, in a comment:
so you mean if I have 5 threads started from the main thread & If I call fork from one of the thread, the rest four thread will be killed?
After the fork
call, the parent process still will have five threads, but the child process will have only one.