MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
Qtの応用 - 多重起動の禁止のソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
Qtの応用 - 多重起動の禁止
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == ソフトウェアのインスタンスを1つだけ実行(多重起動を禁止)する理由として、<br> メモリリークの問題を制限する、または、リソース、ファイル、データベース等をアプリケーションの2つのインスタンスが奪い合うことで起こる問題を排除するためである。<br> また、原則として、ユーザが使用するアプリケーションのコピーは1つだけでよい場合もある。<br> <br> 多重起動を禁止する方法には、以下に示す2つの方法がある。<br> * QLockFileの使用 *: 一時的なファイルが作成されて、ソフトウェア終了時に破棄する。 *: これは、ソフトウェアを多重起動された時、その一時ファイルの存在を確認して、一時ファイルが存在するならばインスタンスを自動的に閉じる。 *: <br> * QSystemSemaphoreとQSharedMemoryの使用 *: 共有メモリセグメントを作成して、一意の識別子を持つ既存のセグメントに接続する。 *: 接続に成功した場合、ソフトウェアのインスタンスが既に作成されているため、そのことをユーザに通知してソフトウェアを終了する。 *: 接続に失敗した場合、ソフトウェア用のメモリセグメントを作成して、最初のインスタンスを実行する。 <br><br> == QLockFileの使用 == ソフトウェアの起動時に作成された一時ファイル(Lock File)の作成に失敗する場合、<br> 既にソフトウェアのインスタンスが存在すると仮定して、ユーザに通知してソフトウェアを終了する。<br> <br> QLockFileは、ソフトウェアの実行インスタンスの数を制限する。<br> ただし、QLockFileの使用は、ユーザのパーミッションに問題がある場合は使用できない可能性がある。<br> <br> <u>※注意</u><br> <u><uniq id>は、任意のIDに置き換えること。</u> <syntaxhighlight lang="c++"> #include <QApplication> #include <QLockFile> #include <QDir> #include <QMessageBox> #include "CMainWindow.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); QLockFile lockFile(QDir::temp().absoluteFilePath("<uniq id>.lock")); // Trying to close the Lock File, if the attempt is unsuccessful for 100 milliseconds, // then there is a Lock File already created by another process. // Therefore, we throw a warning and close the program if(!lockFile.tryLock(100)) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setText("The application is already running.\n" "Allowed to run only one instance of the application."); msgBox.exec(); return -1; } CMainWindow w; w.show(); return a.exec(); } </syntaxhighlight> <br><br> == QSystemSemaphoreとQSharedMemoryの使用 == QSharedMemoryは、1台のPC上において、同時に作業しているすべてのユーザーに共有されるものである。<br> これは、システム全体として、ソフトウェアの単一インスタンスの実行を制限する場合等に使用する。<br> したがって、1人のユーザがソフトウェアを実行する場合、他のユーザは同一のソフトウェアを実行することはできない。<br> <br> しかし、各プラットフォームによる共有メモリの違いが存在する。<br> Windowsの場合、共有メモリはプログラムが正常に終了した時および緊急事態が発生した時に解放される。<br> Linux / Unixの場合、緊急時にクラッシュしたメモリは解放されない。<br> <br> 以下の例では、同一のソフトウェアの複数のインスタンスが同時に起動した場合の問題を解決するために使用される。<br> <br> セマフォはメータで作成されて、その最大数は1になる。<br> セマフォを解除する時、ソフトウェアの他の全てのインスタンスは共有メモリにアクセスできないため、完全に所有するリソースの1つのコピーを持つ。<br> このコピーは、ソフトウェアに対応する共有メモリセグメントの識別子の存在により、ソフトウェアの別のインスタンスの実行をチェックする。<br> 共有メモリセグメントのコピーは、正常に起動する時かつ別のソフトウェアインスタンスの情報が見つからない場合に作成される。<br> その後、セマフォが下げられて、実行するソフトウェアの別のインスタンスが許可される。<br> <br> <u>※注意</u><br> <u><uniq id 1>および<uniq id 2>は、任意のIDに置き換えること。</u> <syntaxhighlight lang="c++"> #include <QApplication> #include <QSystemSemaphore> #include <QSharedMemory> #include <QMessageBox> #include "CMainWindow.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); QSystemSemaphore semaphore("<uniq id 1>", 1); // create semaphore semaphore.acquire(); // Raise the semaphore, barring other instances to work with shared memory #ifndef Q_OS_WIN32 // in linux / unix shared memory is not freed when the application terminates abnormally, // so you need to get rid of the garbage QSharedMemory nix_fix_shared_memory("<uniq id 2>"); if(nix_fix_shared_memory.attach()) { nix_fix_shared_memory.detach(); } #endif QSharedMemory sharedMemory("<uniq id 2>"); // Create a copy of the shared memory bool is_running; // variable to test the already running application if(sharedMemory.attach()) { // We are trying to attach a copy of the shared memory // To an existing segment is_running = true; // If successful, it determines that there is already a running instance } else { sharedMemory.create(1); // Otherwise allocate 1 byte of memory is_running = false; // And determines that another instance is not running } semaphore.release(); // If you already run one instance of the application, then we inform the user about it // and complete the current instance of the application if(is_running) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setText("The application is already running.\n" "Allowed to run only one instance of the application."); msgBox.exec(); return -1; } CMainWindow w; w.show(); return a.exec(); } </syntaxhighlight> <br><br> == QLocalServer / QLocalSocketの使用 == 処理の流れを以下に示す。<br> # <code>QSharedMemory</code>を使用して、アプリケーションの単一インスタンスを保証する。 # <code>QLocalServer</code>と<code>QLocalSocket</code>を使用して、既存のインスタンスと新しいインスタンス間で通信を行う。 # SingleInstanceクラスのインスタンスを生成して、単一インスタンス制御のロジックをカプセル化する。 # SingleInstanceクラスのtryToRunメソッド実行して、アプリケーションが実行可能かどうかを確認する。 # 既存のインスタンスが検出された場合、sendMessagスロットを使用してそのインスタンスにメッセージを送信する。<br><u>ロック向け一時ファイルが、/tmp/MyAppServerファイルが自動的に生成される。</u> # 既存のインスタンスは、messageReceivedシグナルを通じてメッセージを受信して、適切に対応する。<br>(例: ウインドウのアクティブ化等) <br> これにより、アプリケーションの多重起動を効果的に防ぎつつ、既存のインスタンスとの通信も可能となる。<br> 既存のインスタンスと通信する機能により、より柔軟で拡張性の高い設計になっている。<br> <br> 必要に応じて、messageReceivedシグナルのハンドラを拡張して、既存のウインドウをアクティブにする等の処理を追加する。<br> <code>QLocalServer</code>と<code>QLocalSocket</code>を使用するには、Qt Networkモジュールが必要となる。<br> * Qtプロジェクトファイル (.pro) を使用する場合 <syntaxhighlight lang="make"> QT += network </syntaxhighlight> <br> * CMakeLists.txtファイルを使用する場合 <syntaxhighlight lang="cmake"> find_package(Qt6 REQUIRED COMPONENTS Network) target_link_libraries(SingleInstanceApp PRIVATE Qt6::Network ) </syntaxhighlight> <br> <br><br> __FORCETOC__ [[カテゴリ:Qt]]
Qtの応用 - 多重起動の禁止
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse