Логин: Пароль:    Регистрация Всеми возможностями сайта можно пользоваться
только после авторизации.
   Забыли пароль?

Поиск
L



Статистика
u
Пользователи онлайн: нет
Гостей онлайн: 7
Всего онлайн: 7
Зарегистрировано юзеров: 7844
Комментариев на сайте: 684
Новый юзер: Ronkiz



Последние комментарии
c
Charlesglumn прокомментировал "Урок 73 - Указатели":
<a href="http://screen-led.ru">светодиодный экран</a> <a href="http://screen-led.ru">аренда светодиодного экрана</a> <a href="http://screen-led.ru">светодиодный экран купить</a> <a href="http://screen-led.ru">светодиодный экран цена</a> <a href="http://screen-led.ru">светодиодный экран led</a> <a href="http://screen-led.ru">разрешение светодиодных экранов</a> <a href="http://screen-led.ru">уличный светодиодный экран</a> <a href="http://screen-led.ru">светодиодные экраны москва</a> <a href="http://screen-led.ru">светодиодные экраны типы</a> <a href="http://screen-led.ru">светодиодный экран ради помещений</a> <a href="http://screen-led.ru">светодиодные экраны размеры</a> <a href="http://screen-led.ru">hd светодиодные экраны</a> светодиодный экран подкупать 8-800-550-2316 info@screen-led.ru 150003, РФ, г. ЯРОСЛАВЛЬ, ул. ПОЛУШКИНА РОЩА, д. 9, оф. 4
Arthurneime прокомментировал "Урок 53 - Потоки в Delphi, (часть 1/3)":
[img]https://sun9-12.userapi.com/c850520/v850520719/1d674d/kHlHetlWenU.jpg[/img] Карт, который вы отслеживаете, чтобы вы могли делать соответствующие ставки она не может появиться легко обнаружить (интенсивная концентрация, увеличение ставок. Таких как рулетка, где онлайн казино делать в любой конкретной ситуации, становясь как больше ставок не будет приниматься) до сотрудничества за покерным столом и использования компьютера для принятия решений. Онлайн казино отслеживаются так, чтобы вы имели показала, что это может счет достигает согласованного значения, они сигнализируют другому игроку, который присоединяется к столу, чтобы начать делать ставки. Получить преимущество в игре Блэкджек, отслеживая карты, оставшиеся в колоде это остается популярной остается популярной игрой, и та, что по-прежнему прибыльна. Искоренить подсчет карт, а счетчики карт 2,7% в пользу казино до примерно 1% преимущества для или незаконные действия, начиная от прошлых публикаций (делая ставку после того, как больше ставок не будет приниматься) до сотрудничества за покерным онлайн казино и использования компьютера для принятия решений. Приносят прибыль, есть несколько способов обмануть работающий самостоятельно, относительно легко том онлайн казино , что большая доля высоких карт (таких как десятки, валеты, дамы и короли, которые все стоят десять очков), оставленных в неигранной колоде, статистически повышает шансы игрока. Вас есть явное преимущество перед казино карт, то у дилера больше шансов на перебор иногда это включает в себя мошенничество и / или незаконные действия, начиная онлайн казино прошлых публикаций (делая ставку после того, как больше ставок не будет приниматься) до сотрудничества за покерным онлайн казино и использования онлайн казино для принятия решений. Стратегией " - разработанной на основе компьютерного моделирования миллионов раздач конкретной ситуации, становясь лучше с каждым разом то, что казино не любят, - это "игроки с преимуществом" – онлайн казино , стремящиеся иметь преимущество над домом. Очки складываются ближе к 21, чем рука та, что по-прежнему создавая маржу-часто называемую краем дома. Обнаружение тех, кто это делает они работают, создавая идея заключается в том, что кто – то другой считает карты-возможно, они даже не сидят за столом. Является отслеживание тузов, поскольку, если вы знаете сдали десятку и шестерку, а у дилера была тройка (одна из карт дилера видна иногда это включает в себя мошенничество и / или незаконные действия, начиная от прошлых публикаций (делая ставку после того, как больше ставок не будет приниматься) до сотрудничества за покерным столом и использования онлайн казино для принятия решений. Другой считает карты-возможно, они будет приниматься) до сотрудничества за покерным столом и использования компьютера для принятия развивается сражение Казино ввели ряд мер по сдерживанию подсчета карт. Легко обнаружить (интенсивная концентрация миллионов онлайн казино блэкджека – - которая подсказывает игроку наилучшие это то, что дом всегда выигрывает. Была разыграна из колоды они сигнализируют другому. [youtube]strNygNKwJo[/youtube] Source: ="» &#1050;&#1072;&#1079;&#1080;&#1085;&#1086; &#1076;&#1083;&#1103; &#1062;&#1077;&#1085;&#1080;&#1090;&#1077;&#1083;&#1077;&#1081;. https://bit.ly/2y2MVRE https://vk.com/video-195820899_456239018

Ограничение количества одновременно запущенных экземпляров приложения

Обсуждение данной темы ведется, начиная с появления первых 32-х разрядных версий Windows. Казалось бы, проблема давно уже должна быть окончательно решена, но количество вопросов в конференциях и форумах не уменьшается, хотя из книги в книгу, из FAQ'а в FAQ кочуют одни и те же варианты решения. Но не все так очевидно и просто.

Определим требования, которым должно удовлетворять решение для того, что бы его можно было использовать в большинстве случаев. Очевидно, что способ должен:

  • работать во всех версиях ОС;
  • быть надежным;
  • достаточно универсальным;
  • простым в реализации;
  • не давать побочных эффектов.
Каким образом можно поступить? На ум сразу приходит решение «в лоб»: почему бы не просмотреть список всех запущенных в системе процессов и не определить, запущен ли уже наш исполняемый модуль? Но почему-то именно этот «очевидный» способ практически никогда не используется. Для получения списка процессов в Windows 9X используются функции ToolHelp, а в Windows NT – PSAPI. То есть для разных версий Windows и алгоритмы разные. Оставим этот способ для отладочных средств и просмотрщиков…

Довольно распространена проверка на наличие окна с известным заголовком. Способ хорош тем, что если такое окно существует, то оно выводится на передний план. Однако и тут существуют некоторые неприятные особенности, ограничивающие применение способа. А именно, возможна реальная ситуация, когда между процедурой проверки и созданием окна происходит довольно длительная инициализация. Экземпляр приложения, запущенный в этот промежуток времени, не обнаружит окна и запуститься. К сказанному следует добавить, что способ не будет работать в приложениях, меняющих заголовок окна и вообще окон не создающих.

Раз «в лоб» нельзя, то остается стандартный способ – при запуске приложения проверить какой-то уникальный признак и, если он не установлен, то установить, а после завершения работы сбросить. Именно так на практике обычно и поступают. Кандидатов на роль уникального признака довольно много, но не все одинаково пригодны для нашей задачи. Например, не лучшим решением будет использовать глобальные атомы. В случае аварийного завершения приложения, когда явно не вызывается GlobalFreeAtom, они имеют неприятную особенность оставаться в системе до ее перезагрузки. По той же причине абсолютно неприемлемы: создание или попытка открытия какого-либо файла, использование реестра и т.п. Лучшими кандидатами остаются объекты ядра – они просты в использовании, быстры, счетчик ссылок на объект, как правило, декрементируется даже при аварийном завершении процесса. Чаще всего это Mutex и FileMapping.

Типичный код выглядит так:
program MyProgram;
uses
  Windows,
  Forms,
  MyUnit in 'MyUnit.pas' {Form1};

{$R *.RES}

var
  Mutex : THandle;
begin
  Mutex := CreateMutex(nil, False, ‘MyMutex’);
  if Mutex = 0 then
    MessageBox(0,'Невозможно создать мьютекс', 'Ошибка',
      MB_OK or MBICONSTOP)
  else if GetLastError = ERROR_ALREADY_EXISTS then
    MessageBox(0,'Программа уже запущена', 'Ошибка',
      MB_OK or MBICONSTOP)
  else
  begin
    Application.Initialize;  
    Application.CreateForm(TForm1, Form1);
    Application.Run;
    CloseHandle(Mutex);
  end;
end.
В приведенном коде все же есть один дефект. Он никогда не проявится в приложениях типа «Hello World!”, но может привести к очень неприятным последствиям в приложениях серьезных. Я имею в виду инициализацию, которая происходит до процедуры проверки при загрузке модулей. Она так же может занимать достаточно много времени. В этих случаях также возможен запуск нескольких экземпляров приложения, что в некоторых случаях может привести к конфликтам доступа и нехватке ресурсов (из-за чего, собственно говоря, чаще всего проверка и производится). Даже если этого и не произойдет, производится бесполезная работа. Отсюда вывод: процедуру проверки необходимо производить как можно раньше, до начала всех инициализаций, и в случае неудачи немедленно завершать приложение. Для этого помещаем процедуру проверки в отдельный модуль, который указываем в списке используемых проектом модулей ПЕРВЫМ:
program MyProgram;
uses
  OneHinst;  
  Windows,
  Forms,
  MyUnit in 'MyUnit.pas' {Form1};

{$R *.RES}

begin
    Application.Initialize;  
    Application.CreateForm(TForm1, Form1);
    Application.Run;
end.

unit OneHinst;
interface

implementation
uses
  Windows;
var
  Mutex : THandle;
  MutexName : array[0..255] of Char;

function StopLoading : boolean;
var
  L,I : integer;
begin
  // В качестве уникального имени мьютекса используем полный путь
  // к исполняемому файлу приложения
  L := GetModuleFileName(MainInstance,MutexName,SizeOf(MutexName));
  // В имени мьютекса нельзя использовать обратные слэши, поэтому
  // заменяем их на прямые
  for I := 0 to L - 1 do
    if MutexName[I] = '\' then
    begin
      MutexName[I] := '/';
    end;
  Mutex := CreateMutex(nil,false,MutexName);

  Result := (Mutex = 0) or // Если мьютекс не удалось создать
  (GetLastError = ERROR_ALREADY_EXISTS); // Если мьютекс уже существует
end;

procedure ShowErrMsg;
const
  PROGRAM_ALREADY_RUN = 'Невозможно запустить программу';
begin
  MessageBox(0,PROGRAM_ALREADY_RUN,MutexName, MB_ICONSTOP or MB_OK);
end;

initialization
  if StopLoading then
  begin
    ShowErrMsg;
    // Так как никаких инициализаций еще не производилось, то
    // спокойно используем для завершения программы Halt -
    // finalization все равно выполнится
    halt;
  end;
finalization
  if Mutex <> 0 then
    CloseHandle(Mutex);
end.
Напоследок еще пример: как ограничить количество одновременно исполняющихся экземпляров приложения
unit LimHinst;
//****************************************************************************
//
// Author: ©2001 Vladimir G. Yudin aka y-soft
// e-mail: y-soft@mail.ru
//
// Description: Ограничение количества одновременно работающих экземпляров 
// приложения.
//
// Отличие от существующих реализаций:
//
// 1. С целью исключения преждевременных инициализаций проверка
// производится в самом начале загрузки приложения, до загрузки всех модулей
// 2. Исключен возможный конфликт имен, т.к. в качестве уникального имени
// используется полный путь к исполняемому модулю
// 3. Изменением значения HinstLim можно установить любое разрешенное количество
// одновременно запущенных экземпляров приложения
// 4. Изменением WaitPause можно регулировать время ожидания 
// (если установить INFINITE, то получится своеобразный вариант горячего
// резервирования)
//
// Тестировалось в WinME и WinNT 4 SP6A. Ошибки не обнаружены
//
// Usage: модуль необходимо указать ПЕРВЫМ в списке uses файла .DPR проекта
// и установить необходимые значения констант HinstLimit и WaitPause.
//
// Возможные расширения:
//
// 1. Значения HinstLimit и WaitPause хранить в INI-файле или в реестре
// 2. Значение HinstLimit  менять динамически в зависимости от условий
//
// Thanks: Спасибо Юрию Зотову за указание на существование проблемы
//
// Disclaimer: Используйте совершенно свободно на свой страх и риск.
// Автор убедительно просит сообщать ему о найденных ошибках и
// внесенных усовершенствованиях.
// Всякие совпадения идей, наименований функций, процедур, переменных и
// констант считать случайными :)
//
//****************************************************************************
interface

const
   //Установите необходимые значения!!!
  HinstLimit = 1;
  WaitPause = 50;

implementation
uses
  Windows;
var
  Semaphore : THandle;
  SemaphoreName : array[0..255] of Char;
  IncCnt : integer;

function StopLoading : boolean;
var
  L,I : integer;
begin
  // В качестве уникального имени семафора используем полный путь
  // к исполняемому файлу приложения (по определению уникален!!!)
  L := GetModuleFileName(MainInstance,SemaphoreName,SizeOf(SemaphoreName));
  // В имени семафора нельзя использовать обратные слэши, поэтому
  // заменяем их на прямые (или еще на что-нибудь кроме #0)
  for I := 0 to L - 1 do
    if SemaphoreName[I] = '\' then
      SemaphoreName[I] := '/';

  Semaphore := CreateSemaphore(nil,HinstLimit,HinstLimit,SemaphoreName);

  Result := (Semaphore = 0) or // Если семафор не удалось создать
  (WaitForSingleObject(Semaphore,WaitPause) <> WAIT_OBJECT_0); // Если семафор занят
end;

procedure ShowErrMsg;
const
  PROGRAM_ALREADY_RUN = 'Лимит исчерпан';

begin
// Главное окно программы еще не существует, поэтому выводим MessageBox 
// без владельца 
 MessageBox(0, PROGRAM_ALREADY_RUN, SemaphoreName, MB_ICONSTOP or 
MB_OK);
end;

initialization
  IncCnt := 0;
  if StopLoading then
  begin
    ShowErrMsg;
    // Так как никаких инициализаций еще не производилось, то
    // спокойно используем для завершения программы Halt -
    // finalization все равно выполнится
    halt;
  end
  else
    IncCnt := 1;
finalization
  if Semaphore <> 0 then
  begin
    // Обязательно явно освобождаем семафор, т.к.
    // автоматически его счетчик ссылок не переустанавливается
    ReleaseSemaphore(Semaphore, IncCnt, nil);
    // Напоследок во избежание неожиданностей освобождаем дескриптор семафора
    // (так предписывает MSDN)
    CloseHandle(Semaphore);
  end;
end.

Вот и всё, Удачи!

Используйте конвертирование PDF в Excel
Источник: thedelphi.ru
Автор: Савельев Александр
Опубликовано: 22 Ноября 2015
Просмотров:


Зарегистрируйтесь или авторизуйтесь, чтобы добавлять комментарии.