gpt4 book ai didi

c++ - 如何从父线程中提取pthread的taskid(tid)?

转载 作者:太空宇宙 更新时间:2023-11-04 05:10:01 24 4
gpt4 key购买 nike

我正在使用 std::thread 来启动线程。另外,我需要 /proc/[pid]/tasks/[tid] 中提供的工作线程的统计信息。我需要 tid 才能监视线程统计信息。我想知道是否有办法从父线程中提取 tid 。我知道来自工作线程的系统调用 gettid() 返回其 id,但我想要来自主线程而不是从线程的 threadId。有没有办法从 std::thread.get_tid() 的 thread_id 或 std::thread.get_tid() 中提取 tid

我相信可能有更好的方法,请提出建议:)

更新:
How can you get the Linux thread Id of a std::thread()这提供了一些有关从工作线程获取 tid 的信息,增加了线程启动的开销。例如,可以从启动器线程调用 std::thread t = std::thread(&wrapper); t.get_id() 。我正在寻找是否可以以安全的方式从主/启动器线程执行相同的操作。

最佳答案

所有线程都有一个唯一的 ID:
std::thread::id this_id = std::this_thread::get_id();

您可以在程序启动时将其存储在变量中,并且可以从其他线程访问它。

我明白你所说的“父线程”的意思,但即使一个线程生了另一个线程,它们也是 sibling 。

如果您希望线程能够获取每个工作线程的/proc路径,您可以将工作线程对象包装在一个类中,当它启动实际线程时,创建一个主线程稍后可以获取的路径属性。

一个例子:

#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>

#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>

// A base class for thread object wrappers
class abstract_thread {
public:
abstract_thread() {}

abstract_thread(const abstract_thread&) = delete;
abstract_thread(abstract_thread&& rhs) :
m_th(std::move(rhs.m_th)), m_terminated(rhs.m_terminated), m_cv{}, m_mtx{} {}
abstract_thread& operator=(const abstract_thread&) = delete;
abstract_thread& operator=(abstract_thread&& rhs) {
terminate();
join();
m_th = std::move(rhs.m_th);
m_terminated = rhs.m_terminated;
return *this;
}

virtual ~abstract_thread() {
// make sure we don't destroy a running thread object
terminate();
join();
}

virtual void start() {
if(joinable())
throw std::runtime_error("thread already running");
else {
std::unique_lock<std::mutex> lock(m_mtx);
m_terminated = true;
// start thread and wait for it to signal that setup has been done
m_th = std::thread(&abstract_thread::proxy, this);
m_cv.wait(lock, [this] { return m_terminated == false; });
}
}
inline bool joinable() const { return m_th.joinable(); }
inline void join() {
if(joinable()) {
m_th.join();
}
}
inline void terminate() { m_terminated = true; }
inline bool terminated() const { return m_terminated; }

protected:
// override if thread specific setup needs to be done before start() returns
virtual void setup_in_thread() {}
// must be overridden in derived classes
virtual void execute() = 0;

private:
std::thread m_th{};
bool m_terminated{};
std::condition_variable m_cv{};
std::mutex m_mtx{};

void proxy() {
{
std::unique_lock<std::mutex> lock(m_mtx);
setup_in_thread(); // call setup function
m_terminated = false;
m_cv.notify_one();
}
execute(); // run thread code
}
};

// an abstract thread wrapper capable of returning its /proc path
class proc_path_thread : public abstract_thread {
public:
// function to call from master to get the path
const std::string& get_proc_path() const { return m_proc_path; }

protected:
void setup_in_thread() override {
m_proc_path =
std::move(std::string("/proc/")) + std::to_string(syscall(SYS_gettid));
}

private:
std::string m_proc_path{};
};

// two different thread wrapper classes. Just inherit proc_path_thread and implement
// "execute()". Loop until terminated() is true (or you're done with the work)
class AutoStartThread : public proc_path_thread {
public:
AutoStartThread() { start(); }

private:
void execute() override {
while(!terminated()) {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << std::this_thread::get_id() << " AutoStartThread running\n";
}
}
};

class ManualStartThread : public proc_path_thread {
void execute() override {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << std::this_thread::get_id() << " ManualStartThread running\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
};

int main() {
AutoStartThread a;
std::cout << a.get_proc_path() << "\t// AutoStartThread, will have path\n";

ManualStartThread b;
std::cout << b.get_proc_path()
<< "\t// ManualStartThread not started, no path\n";
b.start();
std::cout << b.get_proc_path()
<< "\t// ManualStartThread will now have a path\n";
b.join();

std::this_thread::sleep_for(std::chrono::milliseconds(1500));
// terminate() + join() is called automatically when abstract_thread descendants
// goes out of scope:
//
// a.terminate();
// a.join();
}

可能的输出:

/proc/38207 // AutoStartThread, will have path
// ManualStartThread not started, no path
/proc/38208 // ManualStartThread will now have a path
139642064209664 ManualStartThread running
139642072602368 AutoStartThread running
139642072602368 AutoStartThread running
139642072602368 AutoStartThread running
139642072602368 AutoStartThread running

关于c++ - 如何从父线程中提取pthread的taskid(tid)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56588075/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com