Как обрабатывать несколько параллельных экземпляров одновременно?

Вот в чем проблема: мне не нравятся несколько экземпляров моей программы, поэтому я их отключил. Моя программа открывает определенный тип пантомимы. В моей системе (Ubuntu 12.04), когда я дважды щелкаю один из этих файлов, это выполняется:

/usr/bin/myprogram /path/to/double/clicked/file.myextension

Как я уже сказал, мне не нравятся множественные экземпляры, поэтому, если программа уже запущена и пользователь хочет открыть один из этих файлов, сообщение DBus отправляется в уже экземпляр, чтобы позаботиться об открытом файле. Итак, если есть уже запущенный экземпляр, и пользователь выбирает 3 файла для открытия с помощью моей программы и нажимает кнопку [Enter], система выполняет:

/usr/bin/myprogram /path/to/double/clicked/file1.myextension
/usr/bin/myprogram /path/to/double/clicked/file2.myextension
/usr/bin/myprogram /path/to/double/clicked/file3.myextension

Все эти экземпляры обнаруживают уже запущенный экземпляр и отправляют ему открытый файл. Вообще никаких проблем, пока.

Но что, если уже нет запущенного экземпляра, и пользователь хочет открыть 3 файла вместе с моей программой? Система вызовет одновременно, снова:

/usr/bin/myprogram /path/to/double/clicked/file1.myextension
/usr/bin/myprogram /path/to/double/clicked/file2.myextension
/usr/bin/myprogram /path/to/double/clicked/file3.myextension

и каждый из этих экземпляров поймет, что уже запущен экземпляр, он попытается отправить сообщение DBus в уже запущенный экземпляр и завершит работу. Итак, все 3 процесса будут делать одно и то же, и ничего не запустится.

Как я могу избежать этой проблемы?

PS: Чтобы определить, есть ли уже запущенные экземпляры, я реализую следующий код:

bool already_runs(){
return !system("pidof myprogram | grep \" \" > /dev/null");
}

person hytromo    schedule 24.07.2012    source источник
comment
При открытии нескольких файлов не следует ли передавать все три пути одной команде? Например. /usr/bin/myprogram файл1 файл2 файл3   -  person Alan    schedule 24.07.2012
comment
@Alan: независимо от того, работает это или нет, по крайней мере существует вероятность того, что кто-то может запустить программу три раза подряд с помощью каких-либо других средств :-) Нужен способ, чтобы одна из копий программы объявить себя первым. Например, это может быть получено путем получения блокировки на определенный файл, но я не знаю QT, и это был бы бессмысленный ответ, если QT предоставляет какой-то механизм для помощи.   -  person Steve Jessop    schedule 24.07.2012
comment
Вам нужно обнаружить не только то, что запущен другой экземпляр, но и то, что есть работающий экземпляр, который признал, что это один экземпляр.   -  person bames53    schedule 24.07.2012
comment
@ Алан, я знаю, я думал об этом, и моя программа может обрабатывать это таким образом (она может обрабатывать как аргументы: моя программа файл1 файл2 файл3 и т. д.), но система вызывает мою программу 3 раза по-разному   -  person hytromo    schedule 24.07.2012


Ответы (2)


Я бы использовал некоторую общую память для хранения pid первого процесса. Здесь вам поможет класс QSharedMemory.

Первое, что должна сделать ваша программа, это попытаться создать сегмент разделяемой памяти (используя придуманный вами ключ) и сохранить в нем ваш pid. Если вызов создания не удался, вы можете вместо этого попытаться подключиться к сегменту. Если это удастся, вы можете прочитать pid исходного процесса из него.

РЕДАКТИРОВАТЬ: также не забудьте использовать lock() перед записью или чтением из общей памяти, а затем вызовите unlock(), когда закончите.

person Alan    schedule 24.07.2012
comment
Ссылка больше не работает, вот справочник по Qt 4.8 для QSharedMemory и справочник по Qt 5.5 для QSharedMemory. - person basic6; 25.10.2015

Стандартный способ сделать это в DBus — получить имя вашего приложения на шине; один экземпляр выиграет гонку и может стать работающим экземпляром.

Однако вы сможете сделать это, используя функции Qt, которые будут лучше интегрироваться с остальной частью вашего приложения; см. Qt: передовой опыт для защиты одного экземпляра приложения.

person ecatmur    schedule 24.07.2012