Skip to content

Instantly share code, notes, and snippets.

@unix-beard
Created June 28, 2013 19:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save unix-beard/5887218 to your computer and use it in GitHub Desktop.
Save unix-beard/5887218 to your computer and use it in GitHub Desktop.
scan linux procfs - C++ version
#include <thread>
#include <condition_variable>
#include <iostream>
#include <cstdlib>
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
std::vector<fs::path> proc_pids;
std::condition_variable rescan_proc_cv;
std::mutex g_mutex;
bool rescan_proc = false;
bool rescan_proc_done = false;
void get_proc_pids()
{
proc_pids.clear();
fs::directory_iterator end;
fs::path proc = "/proc/";
auto lambda = [](const std::string& s) { return std::all_of(s.begin(), s.end(), ::isdigit); };
for (fs::directory_iterator iter(proc); iter != end; ++iter)
{
if (lambda(iter->path().stem().string()))
{
proc_pids.push_back(iter->path());
}
}
}
void find_top(const fs::path& pid_path)
{
std::string s(pid_path.string().rbegin(), pid_path.string().rend());
}
void search(bool flag)
{
auto tid = std::this_thread::get_id();
while (true)
{
{
std::unique_lock<std::mutex> lk(g_mutex);
std::cout << "Search thread [tid=" << tid << "] is waiting\n";
rescan_proc_cv.wait(lk, []{ return rescan_proc; });
}
std::cout << "Search thread [tid=" << tid << "] is scanning...\n";
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
auto start = std::chrono::steady_clock::now();
if (flag)
std::for_each(proc_pids.begin(), proc_pids.begin() + proc_pids.size() / 2, find_top);
else
std::for_each(proc_pids.rbegin(), proc_pids.rbegin() + proc_pids.size() / 2, find_top);
auto end = std::chrono::steady_clock::now();
{
std::lock_guard<std::mutex> ulock(g_mutex);
std::cout << tid << ": Scanning ok. Size: " << proc_pids.size() << std::endl;
std::cout << tid << ": " << std::chrono::duration<double, std::milli>(end - start).count() << " ms" << std::endl;
rescan_proc_done |= true;
}
rescan_proc_cv.notify_one();
}
}
int main()
{
std::thread t1(search, true);
std::thread t2(search, false);
t1.detach();
t2.detach();
while (true)
{
get_proc_pids();
{
std::lock_guard<std::mutex> lk(g_mutex);
std::cout << "Issuing rescan command...\n";
rescan_proc = true;
}
rescan_proc_cv.notify_all();
{
std::unique_lock<std::mutex> lk(g_mutex);
std::cout << "Main thread [tid=" << std::this_thread::get_id() << "] is waiting for workers to finish rescan...\n";
rescan_proc_cv.wait(lk, []{ return rescan_proc_done; });
}
{
std::lock_guard<std::mutex> lk(g_mutex);
std::cout << "Main thread [tid=" << std::this_thread::get_id() << "] all workers finished rescan\n";
rescan_proc = false;
rescan_proc_done = false;
}
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment