我有一个
decode
函数,可以解码字符串并在内部使用映射来存储已解码的值以提高效率。该函数由多个线程访问(使用pthread
),因此为了防止地图并发访问问题,我添加了一个std::mutex
。然而,在添加互斥体后,我注意到一些线程最终停止工作或似乎被卡住。当我删除互斥锁时,所有线程都运行没有任何问题。
我的问题是:这可能是饥饿的情况吗?我该如何解决这个问题?
其他上下文:此 C++ 代码正在通过 JNI 在 Android 应用程序中使用。
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());
}
请勿从具有多个活动线程的程序中调用
fork
。 Android 操作系统基于 Linux 内核,Linux 的man 2 fork
页面是这样说的:
• 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).
除了调用
fork
的线程之外的所有线程都将从子进程中消失。如果其中任何一个互斥体被锁定,那么该互斥体将保持锁定状态,无法解锁。如果其中任何一个有正在进行的工作,那么该工作将是未完成的,(通常)您无法知道已经完成了多少。
您在评论中问:
所以你的意思是如果我有 5 个从主线程启动的线程并且如果我从其中一个线程调用 fork,那么剩下的 4 个线程将被杀死?
在
fork
调用之后,父进程仍然有五个线程,但子进程只有一个。