GTKmm (3.0) と glade によるアプリ (6) - (Qtでも使える)アプリケーションの多重起動の防止 v2
今回は、前回の"GTKmm (3.0) と glade によるアプリ (5) - アプリケーションのアイコンをセット "で作成したプログラムをベースに、アプリケーションの多重起動の防止の改良を行います。
今回改良で、もう少しだけシステム負荷を抑えたいと思います。
今回、修正したソースは main.cc 内の chk_multiple_startup という関数だけです。
前回まで
"ps x | grep %s"
により ps コマンドの結果を grep にて抽出しています。
これだと、2つのコマンドをごく短時間といえ実行しています。
そこで、以下のように ps コマンド内で完結するようにします。
"ps --no-headers -o '%%c' -C %s"
これにより、%s で指定したコマンドプロセス名のみの結果を取得することができます。
ps コマンドの引数の説明をしますと、
"--no-headers" :出力にヘッダーを表示しない
"-o '%%c'" :プロセスのコマンドのみ出力
" -C %s" :%s で指定したコマンドプロセスのみを対象
これにより、ps コマンドのみで処理することができるようになります。
起動されていた場合はプロセスのコマンドと改行コードを出力し、起動されていなかった場合は改行コードのみ出力します。
今回修正したソース main.cc
今回の変更に伴って、ps コマンドの出力結果の処理ロジックも若干ですが修正していますので確認してください。#include "MainWindow.h" Glib::RefPtr<Gtk::Builder> refBuilder; bool chk_multiple_startup(const gchar *); /******************************************************************************* main *******************************************************************************/ int main(int argc, char* argv[]) { Gtk::Main kit(&argc, &argv); // multiple startup check const gchar *appname = g_get_application_name(); if (!chk_multiple_startup(appname)){ std::cout << "this application has already been started :" << appname << std::endl; return 1; } try { refBuilder=Gtk::Builder::create_from_file("paned_test.glade"); } catch(const Glib::FileError& ex) { std::cerr << "FileError: " << ex.what() << std::endl; return 1; } catch(const Glib::MarkupError& ex) { std::cerr << "MarkupError: " << ex.what() << std::endl; return 1; } catch(const Gtk::BuilderError& ex) { std::cerr << "BuilderError: " << ex.what() << std::endl; return 1; } MainWindow* m_main = nullptr; refBuilder->get_widget_derived("mainWindow", m_main); if (m_main){ kit.run(*m_main); delete m_main; return 0; } std::cerr << "mainWindow load failed\n" << std::endl; delete m_main; return 1; } bool chk_multiple_startup(const gchar *process_name) { FILE *fp; char str[256]; int ncnt; ncnt=0; // sprintf(str,"ps x | grep %s",process_name); sprintf(str,"ps --no-headers -o '%%c' -C %s",process_name); if ((fp=popen(str,"r"))==NULL) return(true); while(1){ if(fgets(str,255,fp)==NULL){ break; } if (strlen(str)>1) ncnt++; if(feof(fp)){ break; } } pclose(fp); if (ncnt>1){ return(false); } return(true); }
今回はzipファイルは用意していません。
簡単でしたね!
Qt, GTK+ のこんな入門書はいかがでしょうか?
Qtで簡単 GUIプログラミング―Qt入門書を読む前に読む「入門書」
- 作者: 曹よしひろ
- 出版社/メーカー: カットシステム
- 発売日: 2009/04
- メディア: 単行本
- クリック: 24回
- この商品を含むブログ (6件) を見る
- 作者: 田中ひろゆき
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 1999/08
- メディア: 単行本
- クリック: 4回
- この商品を含むブログを見る