From 7361b79da6f611478428ebac022ad41a22414c85 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Sun, 5 Feb 2023 00:44:21 +0100 Subject: Added number_of_threads() --- debian/changelog | 6 ++++++ process.cpp | 43 ++++++++++++++++++++++++++++++++++--------- process.h | 2 ++ tests/test-process.cpp | 12 +++++++++++- 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/debian/changelog b/debian/changelog index 2f91dac..8f473aa 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +libreichwein (1.4~pre1) UNRELEASED; urgency=medium + + * Added number_of_threads() + + -- Roland Reichwein Sun, 05 Feb 2023 00:25:04 +0100 + libreichwein (1.3) unstable; urgency=medium * Fixed upload in Makefile diff --git a/process.cpp b/process.cpp index 67cf1ce..c504330 100644 --- a/process.cpp +++ b/process.cpp @@ -16,23 +16,48 @@ namespace fs = std::filesystem; bool Reichwein::Process::is_running(pid_t pid) { - fs::path pid_file{"/proc/" + std::to_string(pid) + "/stat"}; - if (!fs::exists(pid_file)) - return false; + // 3rd position is status for pid + fs::path pid_file{"/proc/" + std::to_string(pid) + "/stat"}; + if (!fs::exists(pid_file)) + return false; - std::string s{Reichwein::File::getFile(pid_file)}; + std::string s{Reichwein::File::getFile(pid_file)}; - auto pos0{s.find(' ', 0)}; + auto pos0{s.find(' ', 0)}; + pos0 = s.find(' ', pos0 + 1); + pos0++; + + auto pos1{s.find(' ', pos0 + 1)}; + + std::string state{s.substr(pos0, pos1 - pos0)}; + + return state == "R" || state == "S"; +} + +int Reichwein::Process::number_of_threads(pid_t pid) +{ + // 20th position is the number of threads for pid + fs::path pid_file{"/proc/" + std::to_string(pid) + "/stat"}; + if (!fs::exists(pid_file)) + return false; + + std::string s{Reichwein::File::getFile(pid_file)}; + + size_t pos0{}; + for (int i = 0; i < 19; i++) { pos0 = s.find(' ', pos0 + 1); - pos0++; + if (pos0 == std::string::npos) + throw std::runtime_error("Bad format in /proc/" + std::to_string(pid) + "/stat"); + } - auto pos1{s.find(' ', pos0 + 1)}; + size_t pos1{s.find(' ', pos0 + 1)}; - std::string state{s.substr(pos0, pos1 - pos0)}; + std::string number_of_threads_s{s.substr(pos0, pos1 - pos0)}; - return state == "R" || state == "S"; + return std::stoi(number_of_threads_s); } + // tcp: tcp or tcp6 bool Reichwein::Process::tcp_is_pid_listening_on(const std::string& tcp, pid_t pid, int port) { diff --git a/process.h b/process.h index fb24017..b01778c 100644 --- a/process.h +++ b/process.h @@ -10,6 +10,8 @@ namespace Reichwein::Process { EXPORT bool is_running(pid_t pid); +EXPORT int number_of_threads(pid_t pid); + EXPORT bool unix_is_pid_listening_on(pid_t pid, const std::string& path); EXPORT void wait_for_pid_listening_on(pid_t pid, const std::string& path); diff --git a/tests/test-process.cpp b/tests/test-process.cpp index dfee83f..9855546 100644 --- a/tests/test-process.cpp +++ b/tests/test-process.cpp @@ -1,5 +1,7 @@ #include +#include + #include "process.h" #include @@ -23,7 +25,7 @@ protected: }; -TEST_F(ProcessTest,is_running) { +TEST_F(ProcessTest, is_running) { auto pid{::getpid()}; EXPECT_NE(pid, -1); @@ -32,3 +34,11 @@ TEST_F(ProcessTest,is_running) { EXPECT_EQ(Reichwein::Process::is_running(999999999), false); } + +TEST_F(ProcessTest, number_of_threads) { + EXPECT_EQ(Reichwein::Process::number_of_threads(::getpid()), 1); + std::thread t1{[](){std::this_thread::sleep_for(std::chrono::milliseconds(50));}}; + EXPECT_EQ(Reichwein::Process::number_of_threads(::getpid()), 2); + t1.join(); + EXPECT_EQ(Reichwein::Process::number_of_threads(::getpid()), 1); +} -- cgit v1.2.3