Возможно ли синхронизовать процессы используя имя исполняемо
От: MaLS Россия https://github.com/maliutin
Дата: 15.02.22 09:31
Оценка:
Копаюсь в очень легаси коде, в котором наткнулся а то, что повторный запуск exe файла контролируется по средствам проверки наличия процесса с таким же именем.

Утрированно код написанный под .net 4.5 выглядит так:

using System;
using System.Diagnostics;

namespace ConsoleApp6
{
    class Program
    {
        static void Main(string[] args)
        {
            if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1)
            {
                Console.WriteLine("ALREADY RUNNING");
                return;
            }

            Console.WriteLine("RUN");
        }
    }
}


В своей практике для синхронизации процессов всегда использовал Mutex и как то не задумывался про контроль процессов по имени.

Теперь же требуется обосновать правильность или неправильность такого подхода.

Кинте, пожалуйста, ссылки на документацию или статьи майкрософитовцев, которые говорят что-нибудь о таком подходе.

UPD

Для программы есть требование, что в рамках одного запущенного Windows должен запускаться только один процесс exe файла. В результате исследования кода выяснилось, что это требование реализуется выше представленным алгоритмом. И теперь требуется дать обоснование, что данный код полностью реализует это требование. Если нет, то объяснить почему и поставить в план на переделывание. Под что соответственно будут выделены ресурсы.
----
"Ответить на вопрос — значит согласиться с правильностью его постановки.", Карстен Бредемайер
Отредактировано 15.02.2022 14:03 MaLS . Предыдущая версия .
.net windows
Re: Возможно ли синхронизовать процессы используя имя исполняемого файла?
От: Ночной Смотрящий Россия  
Дата: 15.02.22 09:35
Оценка: +3
Здравствуйте, MaLS, Вы писали:

MLS>Теперь же требуется обосновать правильность или неправильность такого подхода.


У подхода есть потенциальная проблема — имя процесса может и совпать у разных приложений. И есть особенность — глобальный мьютекс ограничен конкретной сессией, а вот список процессов глобален для всей машины. В результате поведение на RDP сервере будет отличаться.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[2]: Возможно ли синхронизовать процессы используя имя исполняемого файла?
От: MaLS Россия https://github.com/maliutin
Дата: 15.02.22 09:48
Оценка: +2
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>У подхода есть потенциальная проблема — имя процесса может и совпать у разных приложений.

Для приложение, которое я просматриваю, не проблема. Там админы гарантируют, что процесса с таким именем не.

НС>И есть особенность — глобальный мьютекс ограничен конкретной сессией, а вот список процессов глобален для всей машины.

А разве это не решается добавлением префикаса Global\?

В документации написано:

On a server that is running Terminal Services, a named system mutex can have two levels of visibility. If its name begins with the prefix "Global\", the mutex is visible in all terminal server sessions. If its name begins with the prefix "Local\", the mutex is visible only in the terminal server session where it was created. In that case, a separate mutex with the same name can exist in each of the other terminal server sessions on the server. If you do not specify a prefix when you create a named mutex, it takes the prefix "Local\". Within a terminal server session, two mutexes whose names differ only by their prefixes are separate mutexes, and both are visible to all processes in the terminal server session. That is, the prefix names "Global\" and "Local\" describe the scope of the mutex name relative to terminal server sessions, not relative to processes.

----
"Ответить на вопрос — значит согласиться с правильностью его постановки.", Карстен Бредемайер
Re: Возможно ли синхронизовать процессы используя имя исполняемого файла?
От: karbofos42 Россия  
Дата: 15.02.22 10:32
Оценка: +1
Здравствуйте, MaLS, Вы писали:

MLS>Копаюсь в очень легаси коде, в котором наткнулся а то, что повторный запуск exe файла контролируется по средствам проверки наличия процесса с таким же именем.


MLS>Утрированно код написанный под .net 4.5 выглядит так:


...

MLS>В своей практике для синхронизации процессов всегда использовал Mutex и как то не задумывался про контроль процессов по имени.


MLS>Теперь же требуется обосновать правильность или неправильность такого подхода.


MLS>Кинте, пожалуйста, ссылки на документацию или статьи майкрософитовцев, которые говорят что-нибудь о таком подходе.


Так задача какая? Лишь бы работало или именно переписать хочется?
Если за много лет не было претензий, то пусть и дальше работает.
Если хочется сделать правильно, то для обоснований много всякого можно придумать.
Тут уже зависит от конкретного приложения. Можно и данные поломать.

Кто-то копирует файл приложения и в одной папке получаются Program.exe и Program_copy.exe. Запускает их одновременно.
Тут можно и какую-нибудь локальную базу сломать и ещё какие-нибудь данные в непонятное состояние перевести, т.к. программа просто никакую синхронизацию не проводит и к такому не готова.
Может и кого другого за собой увести, что сервер перезагружаться придётся. И всё потому, что кто-то файлик случайно/специально переименовал, а не усиленно сидел ломал.
Re[3]: Возможно ли синхронизовать процессы используя имя исполняемого файла?
От: Ночной Смотрящий Россия  
Дата: 15.02.22 10:50
Оценка:
Здравствуйте, MaLS, Вы писали:

НС>>И есть особенность — глобальный мьютекс ограничен конкретной сессией, а вот список процессов глобален для всей машины.

MLS>А разве это не решается добавлением префикаса Global\?

Так надо выяснить как нужно сперва, а потом уже искать решение.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: Возможно ли синхронизовать процессы используя имя исполняемого файла?
От: alexander_r  
Дата: 15.02.22 11:56
Оценка: +3
Здравствуйте, MaLS, Вы писали:
MLS>
MLS>using System;
MLS>using System.Diagnostics;

MLS>namespace ConsoleApp6
MLS>{
MLS>    class Program
MLS>    {
MLS>        static void Main(string[] args)
MLS>        {
MLS>            if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1)
MLS>            {
MLS>                Console.WriteLine("ALREADY RUNNING");
MLS>                return;
MLS>            }

MLS>            Console.WriteLine("RUN");
MLS>        }
MLS>    }
MLS>}
MLS>


Если два процесса стартуют "одновременно", то условие(Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1)может быть у обоих процессов и они оба завершатся, или наоборот, не успеют попасть в список процессов и оба откроются, вручную скорее всего это не воспроизвести, но программно вполне возможно
Re[2]: Возможно ли синхронизовать процессы используя имя исполняемого файла?
От: MaLS Россия https://github.com/maliutin
Дата: 15.02.22 14:10
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Так задача какая? Лишь бы работало или именно переписать хочется?

В рамках одного экземпляра Windows запускать только одни процесс exe файла.

K>Если за много лет не было претензий, то пусть и дальше работает.

Претензии есть. И они пользователей достали. Нет гарантии что программа буде вести себя предсказуемо.

K>Если хочется сделать правильно, то для обоснований много всякого можно придумать.

Нужно гарантировать стабильную работу.

K>Тут уже зависит от конкретного приложения. Можно и данные поломать.

Приложение делает много всего, и считает и в базу без транзакций кладёт. Основная задача чтобы один пользователь не запустил процесс дважды, и второй по RDP не запустил в параллели.
----
"Ответить на вопрос — значит согласиться с правильностью его постановки.", Карстен Бредемайер
Re[2]: Возможно ли синхронизовать процессы используя имя исп
От: MaLS Россия https://github.com/maliutin
Дата: 15.02.22 14:16
Оценка:
Здравствуйте, alexander_r, Вы писали:

_>может быть у обоих процессов и они оба завершатся, или наоборот, не успеют попасть в список процессов и оба откроются, вручную скорее всего это не воспроизвести, но программно вполне возможно


Вот это как раз и нужно обосновать.

P.S.
В программирование это как раз самое запарное доказывать, что кто-то был неправ.
Конечно сдаётся программу As Is, но от этого As Is заказчик уже беситься.
----
"Ответить на вопрос — значит согласиться с правильностью его постановки.", Карстен Бредемайер
Отредактировано 15.02.2022 14:18 MaLS . Предыдущая версия . Еще …
Отредактировано 15.02.2022 14:17 MaLS . Предыдущая версия .
Re[4]: Возможно ли синхронизовать процессы используя имя исполняемого файла?
От: MaLS Россия https://github.com/maliutin
Дата: 15.02.22 14:32
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, MaLS, Вы писали:


НС>Так надо выяснить как нужно сперва, а потом уже искать решение.


Надо в рамках одного экземпляра Windows не допустить повторного запуска exe файла. Т.е. один и то же пользователь не должен запустить exe дважды и второй не должен запустить в параллели.

Сейчас в программе реализован алгоритм:

using System;
using System.Diagnostics;

namespace ConsoleApp6
{
    class Program
    {
        static void Main(string[] args)
        {
            if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1)
            {
                Console.WriteLine("ALREADY RUNNING");
                return;
            }

            Console.WriteLine("RUN");
        }
    }
}


Надо дать ему обоснование, является он рабочим или нет.
----
"Ответить на вопрос — значит согласиться с правильностью его постановки.", Карстен Бредемайер
Re: Возможно ли синхронизовать процессы используя имя исполняемо
От: Sinclair Россия http://corp.ingrammicro.com/Solutions/Cloud.aspx
Дата: 15.02.22 14:46
Оценка: 2 (1)
Здравствуйте, MaLS, Вы писали:

MLS>Кинте, пожалуйста, ссылки на документацию или статьи майкрософитовцев, которые говорят что-нибудь о таком подходе.

https://rsdn.org/article/baseserv/avins.xml
Автор(ы): Dr. Joseph M. Newcomer
Дата: 17.02.2001

В статье подробно рассматриваются различные способы ограничения числа запущенных копий приложения одной. Указываются недостатки и даже ошибки во многих известных методах решения задачи, которые постоянно фигурируют в конференциях и в Сети. Кроме того, указывает на различные трактовки понятия "одна копия приложения" и демонстрирует правильное решение для каждого из случаев.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
http://rsdn.org/File/5743/rsdnaddict.GIF
Re[3]: Возможно ли синхронизовать процессы используя имя исп
От: alexander_r  
Дата: 15.02.22 15:04
Оценка:
Здравствуйте, MaLS, Вы писали:

MLS>Здравствуйте, alexander_r, Вы писали:


_>>может быть у обоих процессов и они оба завершатся, или наоборот, не успеют попасть в список процессов и оба откроются, вручную скорее всего это не воспроизвести, но программно вполне возможно


MLS>Вот это как раз и нужно обосновать.


MLS>P.S.

MLS>В программирование это как раз самое запарное доказывать, что кто-то был неправ.
MLS>Конечно сдаётся программу As Is, но от этого As Is заказчик уже беситься.

тест запускаем несколько процессов с синхронизацией через GetProcessesByName(..), при этом у меня стабильно воспроизводится ситуация, когда условие (Process.GetProcessesByName(procName).Length > 1) во всех процессах и в итоге ничего не открывается, теоретически может случится и запуск двух процессов, но с меньшей вероятностью
        static void Main(string[] args)
        {
            var procName = Process.GetCurrentProcess().ProcessName;
            if (args != null && args.Length > 0)
            {
                Parallel.For(0, 5, new Action<int>(i =>
                {
                    Process.Start(procName + ".exe");
                }));
            }

            if (Process.GetProcessesByName(procName).Length > 1)
            {
                Console.WriteLine("ALREADY RUNNING");
                return;
            }

            Console.WriteLine("RUN");
            Console.ReadKey();

        }


синхронизация через mutex работает всегда
        static void Main(string[] args)
        {
            var procName = Process.GetCurrentProcess().ProcessName;
            if (args != null && args.Length > 0)
            {
                Parallel.For(0, 5, new Action<int>(i =>
                {
                    Process.Start(procName + ".exe");
                }));
                return;
            }

            bool createdNew = false;
            Mutex mutex = null;
            try
            {
                mutex = new Mutex(true, procName, out createdNew);
                if (!createdNew)
                {
                    Console.WriteLine("ALREADY RUNNING");
                    return;
                }


                Console.WriteLine("RUN");
                Console.ReadKey();
            }
            finally
            {
                if (mutex != null)
                {
                    if (createdNew)
                    {
                        mutex.ReleaseMutex();
                    }
                    mutex.Dispose();
                }
            }
        }
Отредактировано 15.02.2022 15:28 alexander_r . Предыдущая версия .
Re[3]: Возможно ли синхронизовать процессы используя имя исполняемого файла?
От: alexander_r  
Дата: 15.02.22 15:25
Оценка:
Здравствуйте, MaLS, Вы писали:

MLS>В рамках одного экземпляра Windows запускать только одни процесс exe файла.

MLS>Претензии есть. И они пользователей достали. Нет гарантии что программа буде вести себя предсказуемо.
MLS>Нужно гарантировать стабильную работу.
MLS>Приложение делает много всего, и считает и в базу без транзакций кладёт. Основная задача чтобы один пользователь не запустил процесс дважды, и второй по RDP не запустил в параллели.
а в чем проблема переделать с тем же mutex-ом, или semaphor-ом?
Process.GetProcessesByName() это же не синхронизирующая функция, при определенных таймингах все может работать, но гарантии что процесс дважды не запуститься при этом нет
Re[4]: Возможно ли синхронизовать процессы используя имя исп
От: MaLS Россия https://github.com/maliutin
Дата: 15.02.22 16:04
Оценка:
Здравствуйте, alexander_r, Вы писали:

_>Здравствуйте, MaLS, Вы писали:


_>тест запускаем несколько процессов с синхронизацией через GetProcessesByName(..), при этом у меня стабильно воспроизводится ситуация, когда условие (Process.GetProcessesByName(procName).Length > 1) во всех процессах и в итоге ничего не открывается, теоретически может случится и запуск двух процессов, но с меньшей вероятностью


Эта ситуация является приемлемой, что два процесса запустились и не один не прошёл точку синхронизации, так как удовлетворяет условию, что два процесса не работаю одновременно.

Для меня в случае с GetProcessesByName нужно подтвердить следующее утверждение:

GetProcessesByName всегда возвращает объект процесса, который стартовал до момента вызова этой функции.


Т.е. вопрос в том если какая-либо синхронизация между стартами процессов, а так же между стартами процесса и списком который получается в методе GetProcessesByName?

_>синхронизация через mutex работает всегда


Подтверждаю.
----
"Ответить на вопрос — значит согласиться с правильностью его постановки.", Карстен Бредемайер
Re[4]: Возможно ли синхронизовать процессы используя имя исполняемого файла?
От: MaLS Россия https://github.com/maliutin
Дата: 15.02.22 16:18
Оценка:
Здравствуйте, alexander_r, Вы писали:

_>Здравствуйте, MaLS, Вы писали:


_>а в чем проблема переделать с тем же mutex-ом, или semaphor-ом?

_>Process.GetProcessesByName() это же не синхронизирующая функция, при определенных таймингах все может работать, но гарантии что процесс дважды не запуститься при этом нет

С технической точки зрения — никакой.

Проект глубокий легаси. Он столько пережил. Так, что не получиться просто прийти и сказать я — супер-пупер программист, а до меня были не компетентные. Надо основание предоставить.

Конечно можно сказать, вот есть надёжная практика с Мьютексами. Но увы этого не хватает для обоснования переделывания. Надо ещё сказать почему предыдущий код не надёжен. Самое трудное в поддержке легаси проектов доказывать что чей-то результат метода Тыка не правильный. А доказывать приходится, потому что надо давать гарантию после переделки. Вот и занимаешься такими изысканиями.
----
"Ответить на вопрос — значит согласиться с правильностью его постановки.", Карстен Бредемайер
Re[5]: Возможно ли синхронизовать процессы используя имя исп
От: alexander_r  
Дата: 15.02.22 16:20
Оценка:
Здравствуйте, MaLS, Вы писали:

MLS>Т.е. вопрос в том если какая-либо синхронизация между стартами процессов, а так же между стартами процесса и списком который получается в методе GetProcessesByName?


мне кажется нужно смотреть реализацию GetProcessesByName(), наверняка там какой нибудь NtQuerySystemInformation используется и с ней разбираться...
Отредактировано 15.02.2022 16:21 alexander_r . Предыдущая версия .
Re[5]: Возможно ли синхронизовать процессы используя имя исполняемого файла?
От: alexander_r  
Дата: 15.02.22 16:30
Оценка:
Здравствуйте, MaLS, Вы писали:
MLS>С технической точки зрения — никакой.

MLS>Проект глубокий легаси. Он столько пережил. Так, что не получиться просто прийти и сказать я — супер-пупер программист, а до меня были не компетентные. Надо основание предоставить.


MLS>Конечно можно сказать, вот есть надёжная практика с Мьютексами. Но увы этого не хватает для обоснования переделывания. Надо ещё сказать почему предыдущий код не надёжен. Самое трудное в поддержке легаси проектов доказывать что чей-то результат метода Тыка не правильный. А доказывать приходится, потому что надо давать гарантию после переделки. Вот и занимаешься такими изысканиями.


как вариант логгировать запуск реального приложения и ловить проблемы, если они возникают у пользователей, это и будет обоснованием к переделыванию
ну или какой то тестовое приложение сделать что бы смоделировать работу реального на котором бы проблема воспроизводилась стабильно...
Re[5]: Возможно ли синхронизовать процессы используя имя исполняемого файла?
От: vaa https://www.youtube.com/playlist?list=PLtrvASfI1KW7VOYRKjglcagQzWLoxlncl
Дата: 16.02.22 03:08
Оценка:
Здравствуйте, MaLS, Вы писали:

MLS>Здравствуйте, alexander_r, Вы писали:


_>>Здравствуйте, MaLS, Вы писали:


_>>а в чем проблема переделать с тем же mutex-ом, или semaphor-ом?

_>>Process.GetProcessesByName() это же не синхронизирующая функция, при определенных таймингах все может работать, но гарантии что процесс дважды не запуститься при этом нет

MLS>С технической точки зрения — никакой.

Почему?
Я так понимаю, прога запускается на ПК пользователя (локально) через ярлык?
Это же слой UI там все выполняется в одном потоке. Т.е. пока процесс не стартует, второй раз кликнуть по ярлыку не получится.
Re[6]: Возможно ли синхронизовать процессы используя имя исполняемого файла?
От: MaLS Россия https://github.com/maliutin
Дата: 16.02.22 06:32
Оценка:
Здравствуйте, vaa, Вы писали:

vaa>Я так понимаю, прога запускается на ПК пользователя (локально) через ярлык?

она может запускаться и через командную строку. По большей части запускается через RDP. Таким образом есть вероятность, что зайдут два пользователя и запустят программу.

vaa>Это же слой UI там все выполняется в одном потоке. Т.е. пока процесс не стартует, второй раз кликнуть по ярлыку не получится.

Windows поваляет различные компоненты UI запускать в разных потоках даже в рамках одной программы (т.е. процесса).
----
"Ответить на вопрос — значит согласиться с правильностью его постановки.", Карстен Бредемайер
Re[6]: Возможно ли синхронизовать процессы используя имя исп
От: MaLS Россия https://github.com/maliutin
Дата: 16.02.22 06:35
Оценка:
Здравствуйте, alexander_r, Вы писали:


_>мне кажется нужно смотреть реализацию GetProcessesByName(), наверняка там какой нибудь NtQuerySystemInformation используется и с ней разбираться...


Да. Придётся идти в ветку Win API
----
"Ответить на вопрос — значит согласиться с правильностью его постановки.", Карстен Бредемайер
Re[7]: Возможно ли синхронизовать процессы используя имя исполняемого файла?
От: vaa https://www.youtube.com/playlist?list=PLtrvASfI1KW7VOYRKjglcagQzWLoxlncl
Дата: 16.02.22 08:34
Оценка:
Здравствуйте, MaLS, Вы писали:

MLS>Здравствуйте, vaa, Вы писали:


vaa>>Я так понимаю, прога запускается на ПК пользователя (локально) через ярлык?

MLS>она может запускаться и через командную строку. По большей части запускается через RDP. Таким образом есть вероятность, что зайдут два пользователя и запустят программу.
Т.е. на серваке тоже можно запустить только один экземпляр? Тогда Global mutex и нечего мучаться.
Хотя, такие вещи, можно настроить приложение чтобы только под конкретным пользователем рдп запускался и другой пользователь будет просто отключать предыдущего даже не завершая работу программы.\

vaa>>Это же слой UI там все выполняется в одном потоке. Т.е. пока процесс не стартует, второй раз кликнуть по ярлыку не получится.

MLS>Windows поваляет различные компоненты UI запускать в разных потоках даже в рамках одной программы (т.е. процесса).
мы же про запуск с ярлыка говорим? Чуйка что клик мышки медленнее чем запуск программы.

еще косяк через процессы, то что путь к исполняемому файлу из дотнета получить сложно. а ведь прога может быть запущена из разных каталогов.
в мьютекс можно путь добавлять.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.