Решено: как сделать невозможным запуск 2х или более копий программы
Модератор: Модераторы разделов
-
truebest
- Сообщения: 18
- ОС: Windows xp
Решено: как сделать невозможным запуск 2х или более копий программы
Собственно сабж
Я понимаю можно поизващаться сделав скрипт который делает ps l ax | grep имя_программы, Но как в самой программе все это сделать...???
-
watashiwa_daredeska
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Решено: как сделать невозможным запуск 2х или более копий программы
Вариантов много. Например, lock file, семафоры POSIX.
Мои розовые очки
-
SLEDopit
- Модератор
- Сообщения: 4824
- Статус: фанат консоли (=
- ОС: GNU/Debian, RHEL
Re: Решено: как сделать невозможным запуск 2х или более копий программы
Сделать ярлык на программу в таком духе:
Код: Выделить всё
[ ! "`ps -A | grep программа`" ] && программаИли вы пишете свою программу и хотите реализовать такую фичу?
update
Блин, не посмотрел на раздел (:
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
The more you believe you don't do mistakes, the more bugs are in your code.
-
truebest
- Сообщения: 18
- ОС: Windows xp
Re: Решено: как сделать невозможным запуск 2х или более копий программы
Да я пишу свою программу, она работает с gpsd цепляется к нему и с gps в бд sqlite ложит инфу, В кронде есть скрипт который проверяет если родной вифи то рубится киллалом моя программа этот файл с бд кидается на сервер, естественно когда нет родной сети то запускается из кронда. Я также понимаю что можно потупому, если файл бд используется вторая копия обламавшись закроется... Попробовал так...неполучается
Хочется чть нибудь в мейне написать как первое условие и все...Системное)
Хочется чть нибудь в мейне написать как первое условие и все...Системное)
-
Doublespace
- Сообщения: 275
- ОС: Debian Lenny,Squeeze,Centos
Re: Решено: как сделать невозможным запуск 2х или более копий программы
В Qt4 решения такие есть. Но у вас на голых сях, как понимаю?
-
truebest
- Сообщения: 18
- ОС: Windows xp
Re: Решено: как сделать невозможным запуск 2х или более копий программы
Правильно, Пишу на простом С,
Потом делаю кросскомпилящию и запускаю это на DIR-320 - D-Link
На дном форуме парня говорил...
Потом делаю кросскомпилящию и запускаю это на DIR-320 - D-Link
На дном форуме парня говорил...
типичная методика это создание pid файла. Монопольно создаю file.pid, при повторном запуске программа пытается пересоздать файл, но не может - значит программа уже работает.
-
eddy
- Сообщения: 3321
- Статус: Красный глаз тролля
- ОС: ArchLinux
Re: Решено: как сделать невозможным запуск 2х или более копий программы
Для гарантии того, что процесс - единственный, я "прибиваю" все одноименные, кроме только что запущенного:
Соответственно, ваша программа должна обрабатывать SIGTERM, чтобы правильно "умереть".
Если же вам нельзя грубо убивать первый экземпляр программы при запуске второго, но надо запретить запуск второго экземпляра, можете создать pid-файл и блокировать его flock'ом.
Код: Выделить всё
//killbrothers.c
#include "killbrothers.h"
#define PROC_BASE "/proc"
int readname(char *name, pid_t pid){ // считать имя процесса из /proc/...
char path[256], nm[512], *ptr;
int cntr = 0, file;
sprintf (path, PROC_BASE "/%d/cmdline", pid);
if((file = open(path, O_RDONLY)) < 0){return 0;}
if(read(file, nm, 512) < 1){return 0;}
if(ptr = strrchr(nm, '/'))
strncpy(name, ptr+1, (int)(nm-ptr+512));
else
strncpy(name, nm, 511);
close(file);
return 1;
}
int killbrothers(){
DIR *dir;
struct dirent *de;
int ret = 2;
pid_t pid, self;
char name[512], myname[512];
if (!(dir = opendir (PROC_BASE))){ // открываем директорию /proc
perror(PROC_BASE);
return 0;
}
self = getpid(); // свой идентификатор
if(!readname(myname, self)) return 0; // свое имя процесса
while ((de = readdir (dir)) != NULL){ // пока не дойдем до конца директории
// пропустим, если директория не указывает на процесс, или указывает на self
if (!(pid = (pid_t) atoi (de->d_name)) || pid == self)
continue;
if(!readname(name, pid)) continue; // считываем имя процесса
if(strncmp(name, myname, 511) == 0){ // если оно совпадает с self
if(kill(pid, SIGTERM) != 0) ret = 0; // убиваем
else ret = 1;
}
}
if(ret == 1)sleep(3); // подождем, пока процесс не умрет окончательно
closedir(dir);
return ret;
}Код: Выделить всё
//killbrothers.h
#ifndef _KILLBROTHERS_H_
#define _KILLBROTHERS_H_
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <getopt.h>
#include <pwd.h>
int killbrothers();
#endif // _KILLBROTHERS_H_Соответственно, ваша программа должна обрабатывать SIGTERM, чтобы правильно "умереть".
Если же вам нельзя грубо убивать первый экземпляр программы при запуске второго, но надо запретить запуск второго экземпляра, можете создать pid-файл и блокировать его flock'ом.
RTFM
-------
KOI8-R - патриотичная кодировка
-------
KOI8-R - патриотичная кодировка
-
sash-kan
- Администратор
- Сообщения: 13939
- Статус: oel ngati kameie
- ОС: GNU
Re: Решено: как сделать невозможным запуск 2х или более копий программы
чуть-чуть информации: http://stackoverflow.com/questions/688343/...id-file-on-unix
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
при сбоях форума см.блог
-
truebest
- Сообщения: 18
- ОС: Windows xp
Re: Решено: как сделать невозможным запуск 2х или более копий программы
Eddy видел только что это, посмотрю попробую... Интересно у меня проблем не возникнет, из за того что я ее в своем приложении fork и execv делаю...
Код: Выделить всё
signal (SIGTERM, die);
signal (SIGQUIT, die);
signal (SIGINT, die);
signal (SIGCHLD, chld_handler);
static void die(void)
{
/* Ignore signals. */
//(void)signal(SIGINT,SIG_IGN);
//(void)signal(SIGHUP,SIG_IGN);
/* We're done talking to gpsd. */
(void)echo();
//(void)endwin();
(void)print_gpx_footer();
(void)gps_close(gpsdata);
/* Bye! */
exit(0);
}
static void print_gpx_footer(void)
{
sqlite3_close(db);
(void)fclose(stdout);
}-
sash-kan
- Администратор
- Сообщения: 13939
- Статус: oel ngati kameie
- ОС: GNU
Re: Решено: как сделать невозможным запуск 2х или более копий программы
p.s. но вообще разруливается это по-другому. в том же крон-задании напишите что-то вроде:
kill -0 $(cat /var/run/myprog.pid) || (myprog & echo $! > /var/run/myprog.pid)
если программа сама демонизируется, то замените «myprog &» просто на «myprog;»
вот, нашёл аналогичную по смыслу тему: Узнать PID
kill -0 $(cat /var/run/myprog.pid) || (myprog & echo $! > /var/run/myprog.pid)
если программа сама демонизируется, то замените «myprog &» просто на «myprog;»
вот, нашёл аналогичную по смыслу тему: Узнать PID
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
при сбоях форума см.блог
-
eddy
- Сообщения: 3321
- Статус: Красный глаз тролля
- ОС: ArchLinux
Re: Решено: как сделать невозможным запуск 2х или более копий программы
Если делаете execv, то прибивать надо не по pid'у, а по ppid'у. Т.е. по любому придется вам родительский pid где-то хранить (если у вас родительский процесс после форка отмирает).
RTFM
-------
KOI8-R - патриотичная кодировка
-------
KOI8-R - патриотичная кодировка
-
truebest
- Сообщения: 18
- ОС: Windows xp
Re: Решено: как сделать невозможным запуск 2х или более копий программы
Вобщем мужики сделал так
Вобщем пид файл создается при создании процесса и убивается при убиении процесса, если файл уже создан то процесс не запускаем, там можно еще чтение из файла делать и проверку по пиду, но и так сойдеt.
А если вырубят свет внезапно то при загрузке системы в rc.local прописал удаление этого пид файла, ну а потом загружаю свое приложение. Вобщем всем спасибо, тему можно закрывать,
Код: Выделить всё
static char *pid_file = "/var/run/cgps.pid";
static void die(int sig UNUSED)
{
(void)print_gpx_footer();
(void)gps_close(gpsdata);
(void)unlink(pid_file);
printf("PZDC \n");
/* Bye! */
exit(0);
}
main
{
FILE *fp;
fp = fopen(pid_file, "r");
if (fp == 0 )
{
printf("Can not open file, tru Create him\n");
if ((fp = fopen(pid_file, "w")) != NULL) {
(void)fprintf(fp, "%u\n", (unsigned int)getpid());
(void)fclose(fp);
}
else {
printf("Can not create file, exit: %s.\n", pid_file);
exit(2);
}
}
else {printf("CGPS already running, exit\n");
exit(2);
}
(void)signal(SIGTERM, die);
(void)signal(SIGQUIT, die);
(void)signal(SIGINT, die);
(void)signal(SIGCHLD, chld_handler);
}Вобщем пид файл создается при создании процесса и убивается при убиении процесса, если файл уже создан то процесс не запускаем, там можно еще чтение из файла делать и проверку по пиду, но и так сойдеt.
А если вырубят свет внезапно то при загрузке системы в rc.local прописал удаление этого пид файла, ну а потом загружаю свое приложение. Вобщем всем спасибо, тему можно закрывать,