我有一个std::thread::id
的集合,我想知道相关std::thread
是否已完成,对于集合中的任何std::thread::id
。
有可能吗?
答案 0 :(得分:1)
不是以便携式方式。通常,您必须让线程设置一个标志,以指示您要测试的实际条件。
答案 1 :(得分:0)
我想我发现了:
struct logger {
enum level : int16_t { debug = 0, info = 1, warn = 2, error = 3, fatal = 4 };
~logger() {
write_all();
}
logger & operator()(level p_level) {
add(true)
<< "[" << get_level(p_level) << "]"
<< "[" << std::time(NULL) << "]"
<< "[" << std::this_thread::get_id() << "] ";
return *this;
}
template <typename T>
logger & operator << (const T & p_val) {
add() << p_val;
return *this;
}
private:
struct at_thread_end {
at_thread_end (std::function<void (std::thread::id)> p_callback
, std::thread::id p_id)
: m_callback(p_callback)
, m_id(p_id){}
at_thread_end(at_thread_end && p_at_thread_end)
: m_callback(std::move(p_at_thread_end.m_callback))
, m_id(std::move(p_at_thread_end.m_id)) {}
at_thread_end & operator=(at_thread_end && p_at_thread_end) {
m_callback = std::move(p_at_thread_end.m_callback);
m_id = std::move(p_at_thread_end.m_id);
return *this;
}
~at_thread_end() {
m_callback(m_id);
}
private:
std::function<void (std::thread::id)> m_callback;
std::thread::id m_id;
};
typedef std::map<std::thread::id, std::stringstream> streams;
void on_thread_end(std::thread::id p_id) {
std::cout << "thread " << p_id << " ended" << std::endl;
streams::iterator _ite = m_streams.find(p_id);
if (_ite != m_streams.end()) {
write(_ite->second.str());
std::lock_guard<std::mutex> _lock(m_mutex_streams);
m_streams.erase(_ite);
}
}
std::stringstream & add(bool p_clean = false) {
std::thread::id _id = std::this_thread::get_id();
streams::iterator _ite = m_streams.find(_id);
if (_ite != m_streams.end()) {
if (p_clean) {
write(_ite->second.str());
_ite->second.str("");
}
return _ite->second;
}
using std::placeholders::_1;
thread_local at_thread_end
_at_thread_end(std::bind(&logger::on_thread_end, this, _1)
,_id);
std::lock_guard<std::mutex> _lock(m_mutex_streams);
m_streams[_id] = std::stringstream();
return m_streams[_id];
}
std::string get_level(level p_level) {
switch (p_level) {
case level::debug:
return "DEB";
case level::info:
return "INF";
case level::warn:
return "WAR";
case level::error:
return "ERR";
case level::fatal:
return "FAT";
}
return "LEVEL UNKNOW";
}
void write(const std::string & p_str) {
std::lock_guard<std::mutex> _lock(m_mutex_write);
if (p_str.size()) {
std::cout << p_str << std::endl;
}
}
void write_all() {
std::lock_guard<std::mutex> _lock(m_mutex_streams);
streams::iterator _end = m_streams.end();
for (streams::iterator _ite = m_streams.begin(); _ite != _end; ++_ite) {
write(_ite->second.str());
}
}
streams m_streams;
std::mutex m_mutex_streams;
std::mutex m_mutex_write;
};
查看完整示例