.gitignore | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
box/center_main.cc | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
box/status_main.cc | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
.gitignore
@@ -6,7 +6,7 @@ utest/utest *.bak gmon.out box/bhshmqbox box/bhshmq_center box/help utest/bhshmq_center */bhshmq_center */help */bhshmqbox */bhshmq_status box/center_main.cc
@@ -20,35 +20,94 @@ #include "center.h" #include "defs.h" #include "signalhandle.h" #include <boost/interprocess/sync/named_mutex.hpp> #include <chrono> #include <thread> using namespace std::chrono_literals; using namespace bhome_shm; namespace { const std::string kCenterRunningFlag = "bh_center_single_flag_0"; class InstanceFlag { public: InstanceFlag(SharedMemory &shm, const std::string &name) : shm_(shm), name_(name), run_(false) {} ~InstanceFlag() { Stop(); } bool TryStartAsFirstInstance() { if (run_) { return true; } auto mtx(shm_.find_or_construct<Mutex>((name_ + "_mutex_0").c_str())()); auto time_stamp(shm_.find_or_construct<int64_t>((name_ + "_timestamp_0").c_str())(0)); if (mtx && time_stamp) { Guard lock(*mtx); auto now = NowSec(); // printf("old: %ld, now: %ld\n", *time_stamp, now); if (now > *time_stamp + 10) { *time_stamp = now; auto UpdateTime = [this, time_stamp]() { while (run_) { std::this_thread::sleep_for(1s); *time_stamp = NowSec(); } }; run_.store(true); std::thread(UpdateTime).swap(worker_); return true; } } return false; } private: void Stop() { run_.store(false); if (worker_.joinable()) { worker_.join(); } } std::thread worker_; SharedMemory &shm_; std::string name_; std::atomic<bool> run_; }; } // namespace int center_main(int argc, const char *argv[]) { auto &shm = BHomeShm(); AppArg args(argc, argv); if (args.Has("remove")) { BHomeShm().Remove(); shm.Remove(); return 0; } bool run = true; auto showStatus = [&]() { auto init = BHomeShm().get_free_memory(); uint64_t idx = 0; while (run) { std::this_thread::sleep_for(1s); printf("%8d shared memory: avail : %ld / %ld\n", ++idx, BHomeShm().get_free_memory(), init); } }; std::thread t(showStatus); InstanceFlag inst(shm, kCenterRunningFlag); if (!inst.TryStartAsFirstInstance()) { printf("another instance is running, exit.\n"); return 0; } BHCenter center(BHomeShm()); if (args.Has("daemon") || args.Has("d")) { int r = daemon(0, 0); // TODO center control msg to close itself. } BHCenter center(shm); center.Start(); printf("center started ...\n"); WaitForSignals({SIGINT, SIGTERM}); run = false; t.join(); return 0; } box/status_main.cc
New file @@ -0,0 +1,100 @@ /* * ===================================================================================== * * Filename: status_main.cc * * Description: * * Version: 1.0 * Created: 2021年04月16日 12时17分07秒 * Revision: none * Compiler: gcc * * Author: Li Chao (), lichao@aiotlink.com * Organization: * * ===================================================================================== */ #include "app_arg.h" #include "box.h" #include "defs.h" #include "shm.h" #include "signalhandle.h" #include <atomic> #include <chrono> #include <thread> using namespace std::chrono_literals; using namespace std::chrono; using namespace bhome_shm; int status_main(int argc, char const *argv[]) { auto &shm = BHomeShm(); std::atomic<bool> run(true); auto Now = []() { return steady_clock::now(); }; auto ToMs = [](auto tp) { return duration_cast<milliseconds>(tp.time_since_epoch()).count(); }; auto showStatus = [&]() { auto next = Now(); const uint64_t start = ToMs(next); auto last = 0; while (run) { std::this_thread::sleep_until(next); auto passed = ToMs(next) - start; auto sec = passed / 1000; auto cur = shm.get_free_memory(); auto Pretty = [](int64_t nbyte) { char sign = '+'; if (nbyte < 0) { nbyte = -nbyte; sign = '-'; } const int Kb = 1024; const int Mb = Kb * 1024; int nmb = nbyte / Mb; auto left = nbyte - nmb * Mb; int nkb = left / Kb; int nb = left - nkb * Kb; char buf[64] = {0}; int n = sprintf(buf, " %4dMb %4dKb %4dB", nmb, nkb, nb); int start = (nmb > 0) ? 0 : ((nkb > 0) ? 7 : 14); buf[start] = sign; return std::string(buf + start); }; char buf[200] = "\n"; auto Print = [&](bool new_line) { int n = sprintf(buf, "\r%6ds avail : %12ld = %s %6ds", sec, cur, Pretty(cur).c_str() + 1, sec); printf("%s", buf); if (new_line) { auto diff = cur - last; printf(" (%+ld = %s)\n", diff, Pretty(diff).c_str()); printf("%s", buf); } fflush(stdout); }; Print(cur != last); last = cur; next += 1000ms; } }; std::thread t(showStatus); WaitForSignals({SIGINT, SIGTERM}); run.store(false); t.join(); return 0; } namespace { static bool install = BoxInstall("bhshmq_status", status_main, "bhome status program."); }