psilogic: (wpriz)
psilogic ([personal profile] psilogic) wrote2015-08-17 08:36 pm

Послание линуксоидам

А вот просветите прожженного вындузоида насчет одной вещи.

Есть ли в линухе хоть какой-нибудь ресурс, который саморазлочивается при грубом убийстве программы? Хочется сделать защиту от одновременного запуска двух instance. Перепробовал уже open(O_EXCL), flock, lockf, shm_open(O_EXCL), sem_open(O_EXCL), sem_trywait - всё либо жидко срёт на локи, либо виснет (lockf(...F_TEST...)), так как, видите ли, файловая система недоразвитая (nfs), либо в случае убиения через kill -9 оставляет ресурс в состоянии, неотличимом от залоченного.

Щито делать? Неужели уних в этом отношении дохлее выньды?

З.Ы. Есть, конечно, сокеты, но это значит юзать "магический номер" порта, что, мягко гойворя, не приветствуется корпоративными традициями кодопейсательства...

З.Ы.Ы. Спасибо всем за мозговой штурм, в конце-концов все заработало по принципу:
1) проверяем, есть ли нужный файл /tmp/чтототам.pid, читаем оттуда pid
2) если есть - проверяем запущен ли такой процесс через signal(pid, 0)
3) если запущен - дополнительно проверяем через readlink(..."/proc/<pid>/exe"...), что этот процесс имеет то же имя, что и текущий

З.Ы.Ы.Ы причины, почему блокируется lockf(...F_TEST...) и flock(...|LOCK_NB...) так и остались невыясненными: блокируется оно даже и не на nfs

[identity profile] theiced.livejournal.com 2015-08-17 05:41 pm (UTC)(link)
очевидно что нету. посему или пидфайл или говно и палки от системд.

[identity profile] scholarpunk.livejournal.com 2015-08-17 06:14 pm (UTC)(link)
Молиться надо!..

[identity profile] metaclass.livejournal.com 2015-08-17 06:32 pm (UTC)(link)
Открыть pidfile и сделать ему сразу unlink при старте?

[identity profile] ujo.livejournal.com 2015-08-17 06:53 pm (UTC)(link)
Дык как все

http://stackoverflow.com/questions/5339200/how-to-create-a-single-instance-application-in-c-or-c

#include <sys/file.h>
#include <errno.h>

int pid_file = open("/var/run/whatever.pid", O_CREAT | O_RDWR, 0666);
int rc = flock(pid_file, LOCK_EX | LOCK_NB);
if(rc) {
if(EWOULDBLOCK == errno)
; // another instance is running
}
else {
// this is the first instance
}
Edited 2015-08-17 18:54 (UTC)