я пытаюсь сделать один экземпляр демона с помощью файла блокировки, но не кажется fcntl()
работать, как ожидалось ...Fcntl F_GETLK всегда возвращает истину
int creat_lock_file (char * pid_fn)
{
struct flock pid_lck = {F_WRLCK, SEEK_SET, 0, 0, 0 };
/* Open/Create pid file */
int pid_fd = open (pid_fn, O_CREAT | O_WRONLY, 0640);
if (pid_fd == -1)
{
syslog (LOG_ERR, "Unable to open PID file > [Errno: %s]", strerror(errno));
return -1;
}
/* Place write lock on pid file */
if (fcntl(pid_fd, F_SETLK, &pid_lck) == -1) {
/* Unhandled error ocured */
syslog (LOG_ERR, "Unhandled error ocured while locking PID file > [Errno: %s]", strerror(errno));
close (pid_fd);
return -1;
}
/* Write PID to lock file */
char pid_lock_buf[11];
sprintf (pid_lock_buf, "%ld\n", (long) getpid());
write (pid_fd, pid_lock_buf, strlen (pid_lock_buf)+1);
return 0;
}
int get_lock_file_status (char * pid_fn)
{
struct flock pid_lck = {F_WRLCK, SEEK_SET, 0, 0, 0 };
/* Open/Create pid file */
int pid_fd = open (pid_fn, O_CREAT | O_WRONLY, 0640);
if (pid_fd == -1)
{
syslog (LOG_ERR, "Unable to open PID file > [Errno: %s]", strerror(errno));
return -1;
}
/* try locking pid file*/
if(fcntl(pid_fd, F_GETLK, &pid_lck) == -1)
{
if(errno == EAGAIN || errno == EACCES) /* file already locked, close fd and return -1 */
{
close (pid_fd);
return -1;
}
else /* Unhandled error ocured */
{
syslog (LOG_ERR, "Unhandled error ocured while locking PID file > [Errno: %s]", strerror(errno));
close (pid_fd);
return -1;
}
}
close (pid_fd);
return 0;
}
так я называю get_lock_file_status
и выхода из него, если возвращает -1, чтобы убедиться, что ни один другой экземпляр не работает, чем я делаю некоторые вещи (fork chdir и т. д.) и вызываю creat_lock_file
для создания и блокировки файла pid после успешного создания демона ...
при выполнении и запуске программы поскольку ожидаемые прогоны создают файл блокировки и записывают pid на него, но когда второй экземпляр запускается, второй экземпляр просто открывает тот же файл блокировки и записывает его собственный pid!
что я делаю неправильно? не должен ли второй экземпляр возвращать -1 в get_lock_file_status
?
это, кажется, неправильный подход. для программирования блокировки файла функция flock() представляется правильным подходом. Эта функция в linux подробно описана в «man 2 flock» или по адресу: –
user3629249
@ user3629249: 'fcntl (2)' с 'F_SET/GET/LK' в порядке, а также POSIX, который' flock (2) 'не является (хотя он широко доступен). Эти два метода имеют различное поведение w.r.t. блокировка наследования и некоторые другие вещи. 'fcntl()' может устанавливать блокировки в области файлов, которые 'flock()' не могут. – Ulfalizer