线程未分离
Threads are not being detached
我正在尝试创建一个线程池。我有一个std::unordered_map
将线程 ID 映射到 std::thread
s ( workers
)。线程 ID 是等待将任务推送到线程池 (waiters
) 的线程的 ID。任务由std::stack
( tasks
) 表示。一旦任务被推入池中,该任务就会从堆栈中弹出,并作为映射的"值"部分变成线程函数。
在析构函数中,我尝试分离所有仍在运行的线程。但我仍然得到以下异常:
terminate called without an active exception
bash: line 7: 16881 Aborted (core dumped) ./a.out
这意味着线程未分离,程序终止。但是我的析构函数会穿过元素并分离它们(我相信)。为什么会发生这种情况,我该如何解决?
#include <queue>
#include <stack>
#include <mutex>
#include <thread>
#include <algorithm>
#include <functional>
#include <type_traits>
#include <unordered_map>
#include <condition_variable>
template <class F>
class thread_pool
{
static_assert(std::is_function<F>::value, "F must have function type");
public:
thread_pool();
~thread_pool();
template <class Task>
void push(Task&&);
private:
std::unordered_map<std::thread::id, std::thread> workers;
std::queue<std::thread> waiters;
std::stack<std::function<F>> tasks;
static std::size_t max;
private:
std::condition_variable m_cond;
std::mutex m;
private:
void wait_for_tasks();
};
template <class F>
std::size_t thread_pool<F>::max(10);
template <class F>
thread_pool<F>::thread_pool()
{
std::lock_guard<std::mutex> lock(m);
for (std::size_t i = 0; i < max; ++i)
waiters.emplace(&thread_pool<F>::wait_for_tasks, this);
}
template <class F>
void thread_pool<F>::wait_for_tasks()
{
while (true)
{
std::unique_lock<std::mutex> lock(m);
m_cond.wait(lock, [this] { return !tasks.empty(); });
auto f = tasks.top();
tasks.pop();
auto& th = workers[std::this_thread::get_id()];
if (th.get_id() == std::thread::id())
th = std::thread(f);
}
}
template <class F>
template <class Task>
void thread_pool<F>::push(Task&& t)
{
{
std::lock_guard<std::mutex> lock(m);
tasks.emplace(std::forward<Task>(t));
}
m_cond.notify_all();
}
template <class F>
thread_pool<F>::~thread_pool()
{
std::for_each(workers.begin(), workers.end(), [] (std::pair<std::thread::id const, std::thread>& p)
{
if (p.second.joinable())
p.second.detach();
});
while (!waiters.empty())
{
auto& t = waiters.front();
waiters.pop();
if (t.joinable())
t.detach();
}
}
int main()
{
thread_pool<void ()> pool;
}
我什至不确定这是最好的方法,这是我第一次做一个。这是一个演示。
在池析构函数中,您在分离线程之前调用pop
,有效地破坏了可连接的线程:标准保证这将调用std::terminate
首先分离线程,然后将其从队列中弹出:
while (!waiters.empty())
{
auto& t = waiters.front();
if (t.joinable())
t.detach();
waiters.pop();
}
相关文章:
- 为什么即使调用了析构函数,C++11 中的分离线程也可以执行
- 多线程减慢程序速度:无错误共享,无互斥锁,无缓存未命中,无小工作量
- 在销毁期间从另一个线程调用对象上调用方法是否未定义行为?
- DirectX 11 -- Hello Triangle 未呈现 -- 原因:运行时库C++多线程
- 检查分离的线程是否还活着?
- 为什么分离线程没有得到输出消息
- 如何"stop"正在等待条件变量的分离线程?
- 线程::加入与分离
- C++ 11 线程在分离后会自动销毁吗?
- 分离线程然后让它超出范围(并使其仍在运行)是否安全?
- 无法永远分离线程 c++
- 访问全局或静态对象的分离线程
- 向量未在分离的线程中推送值
- 为什么std::async与简单的分离线程相比速度较慢
- 如何在 Windows C++ 上分离线程
- 线程未分离
- c++中分离线程的资源释放
- c++分离线程在其关联对象被删除后继续工作
- 分离线程执行结束
- c++ 11线程是否提供了一种在主线程退出后分离线程继续的方法?