案外、UNIX系のC/C++での二重起動/多重起動防止について解説しているサイトがなかなか見つからず、サンプルも見つからないので以下URLを参考にさせて頂き pidfile でやる方法を以下にさくっと。
/var/run/[プログラム名]
のファイルを開き、「ファイルが存在し、そのPIDのプロセスが起動している」なら二重起動。そうでなければ初回起動。
/var/run/[プログラム名]
のファイルが無ければ作って、自分のPIDを書き込み。
この仕組みにより、Ctrl+Cなど予期せぬ終了にも対応です。
Cでやる方は、文字列処理をchar配列とprintf()に読み替えてください(丸投げ)。
sample.cpp
# include <stdio.h>
# include <stdlib.h>
# include <iostream>
int main()
{
{
// 準備
string tmp_path = "/var/run/application"; // アプリ名など適当な被らないファイルを用意
// 自分のPIDを書き出し準備
string pid_write_script = "echo " + to_string(getpid()) + " > " + tmp_path;
// 二重起動のチェック
//bool first = true; // true=初回起動
FILE *tmp_fd = fopen(tmp_path.c_str(), "r");
if (tmp_fd != NULL) {
// pidfile があった
char *cret;
char str[256];
cret = fgets(str, 256, tmp_fd);
fclose(tmp_fd);
if (cret != NULL) {
// pidfile に書かれたPIDを読み込む
char *endp;
errno = 0;
long file_pid = strtol(str, &endp, 10);
if (errno == 0) {
// そのPIDのプログラムが起動中かどうかチェック
string pid_path = "/proc/" + to_string(file_pid);
FILE *pid_fd = fopen(pid_path.c_str(), "r");
if (pid_fd != NULL) {
fclose(pid_fd);
// 二重起動だった
//first = false;
return 1;
}
}
}
}
// 自分のPIDを書き出し
int ret = system(pid_write_script.c_str());
if (ret != 0) {
cout << "unknown error" << endl;
}
}
return 0;
}