是否有可能知道std :: thread是否在给定std :: thread :: id时完成了?

时间:2017-12-04 01:12:44

标签: c++

我有一个std::thread::id的集合,我想知道相关std::thread是否已完成,对于集合中的任何std::thread::id

有可能吗?

2 个答案:

答案 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;

};

您可以在https://pastebin.com/z2HrF70U

查看完整示例