На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
  
> random совсем не рандом , с randomize, разумеется
    Я всю голову себе сломал, пока искал ошибку. У меня одновременно выполняется несколько экземпляров одного процесса, который использует random для создания имени временного файла. И похоже, когда такая операция выполняется в двух процессах в одно и то же время, random в этих процессах иногда генерят одинаковое имя файла. Это я туплю или мне нужен другой random?
    Сообщение отредактировано: shershen -
      randomize инициирует начало последовательности с помощью текущего счетчика времени. Поэтому - да, такое в принципе возможно, хотя и маловероятно, что значения QueryPerformanceCounter совпадут.
      Сообщение отредактировано: MBo -
        Цитата shershen @
        операция выполняется в двух процессах в одно и то же время
        Самым простым выходом будет при создании потока создавать случайное значение для каждого процесса, допустим, от 5 до 21 (либо id назначать потоку, и использовать его за основу) на это время перед вызовом random ложить процесс в сон на его случайное количество миллисекунд. Это решит проблему одновременного опроса счетчика производительности, на основе которого и делается случайное число.
          Цитата simsergey @
          Самым простым выходом будет при создании потока создавать случайное значение для каждого процесса
          Ну, так: бац и совпали эти "случайные" значения. Что делать? :D
            Есть же GetTempFileName, зачем изобретать велосипед?

            В библиотеке DelphiFundamentals есть несколько своих алгоритмов рандома, чё-то там даже можно задавать свою энтропию.

            Ну или крипто-хороший PRNG от synopse
            http://blog.synopse.info/post/AES-CSPRNG
              Цитата shershen @
              Это я туплю или мне нужен другой random?

              Нужно модифицировать инициализацию переменной RandSeed. Например, после вызова Randomize можно поксорить значение RandSeed с GetCurrentThreadID или с Form1.Handle, которые являются уникальными для разных экземпляров одного приложения
              Сообщение отредактировано: leo -
                leo
                Это не гарантирует уникальность результата - идентификаторы могут различаться в тех же битах, что и счетчики.
                  Если нужен совсем-совсем уникальный рэндом - то генери ГУИД.
                  Для менее суровых случаев - #6
                  Для файлов действительно уже есть требуемая функция. К тому же, если файл назначения уже существует, то что мешает повторить генерацию имени until not FileExist?
                    Цитата MBo @
                    Это не гарантирует уникальность результата - идентификаторы могут различаться в тех же битах, что и счетчики.

                    Согласен. Тогда можно как-то так: RandSeed:=(RandSeed shl 16) + GetCurrentThreadID (считаем, что в "нормальных условиях" ID потока не превышает High(word))
                      Цитата MBo @
                      Это не гарантирует уникальность результата - идентификаторы могут различаться в тех же битах, что и счетчики.

                      Можно просто привязаться к астрономической дате и времени запуска процесса (до мс) и(или) ID процесса.
                      (Вряд ли процессы запускаются абсолютно одновременно.)
                      Оба этих параметра могут быть просто составной частью имени файла, без всяких случайных чисел.
                      Если несколько временных файлов процессу одновременно необходимы, в имя или расширение
                      просто добавим счётчик.
                      Сообщение отредактировано: ЫукпШ -
                        ЫукпШ
                        Цитата
                        Можно просто привязаться к астрономической дате и времени запуска процесса (до мс) и(или) ID процесса.
                        (Вряд ли процессы запускаются абсолютно одновременно.)


                        Так автор утверждает, что randomize (который в большинстве случаев нано-микросекундный QueryPerformanceCounter использует), часто дает одинакоый результат.
                        (Правда, его кода мы не видели)
                          Цитата MBo @
                          ЫукпШ
                          Цитата
                          Можно просто привязаться к астрономической дате и времени запуска процесса (до мс) и(или) ID процесса.
                          (Вряд ли процессы запускаются абсолютно одновременно.)


                          Так автор утверждает, что randomize (который в большинстве случаев нано-микросекундный QueryPerformanceCounter использует), часто дает одинакоый результат.
                          (Правда, его кода мы не видели)

                          Так я и говорю:
                          1. для создания имени временного файла случайное число вообще не нужно.
                          Пусть это имя будет состоять из "SomeName"+ID процесса.
                          Или "SomeName" + ID + Date + time (дата и время создания процесса).
                          Понятно, что цифры надо преобразовать в текст.
                          2. 1-е псевдо - случайное число всегда одно и то-же. Подтверждаю.
                          На то оно и псевдо-случайное, и это даже хорошо.
                          (Вообще, это очень ценное свойство.)
                          Дальше можно поступить способом п 1.
                          Возьмём переменные даты и времени при старте программы, как числа, сложим, и "встряхнём" генератор псевдо-случайных чисел
                          столько раз, каким получилась сумма.
                          И после этого будем использовать случайные числа.
                          Чтобы программа, использующая случайные числа работала
                          не одинаково при каждом запуске.
                          ---
                          Но для данного случая случайные числа не годятся в принципе.
                          Что с ними не делай, они могут совпасть.
                          Их использование в данном случае принципиально вредно.
                          Сообщение отредактировано: ЫукпШ -
                            Спасибо большое за ответы! Мне понравился вариант с id процесса и датой, но уже решил проблему по другому.
                              Цитата shershen @
                              но уже решил проблему по другому
                              Как?, если это не секрет..
                                GetTempFile :)
                                  Цитата simsergey @
                                  Как?, если это не секрет..

                                  У меня есть главный процесс, который управляет этими дочерними процессами, вот он один генерит временные имена файлов и раздает дочерним.
                                    Цитата Fr0sT @
                                    Если нужен совсем-совсем уникальный рэндом - то генери ГУИД.

                                    Не спасает при почти одновременной генерации - есть шанс словить два одинаковых значения. Помню, попался бложик одних чуваков, которые сделали первичные ключи в базе на GUID. В тестировании всё было ОК, а вот продакшн начал время от времени сваливаться в key constraint violation. После первой WTF-реакции был набросан синтетический тест, который и показал: параллельная генерация GUID может выдавать дубли.
                                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                    0 пользователей:


                                    Рейтинг@Mail.ru
                                    [ Script execution time: 0,0408 ]   [ 17 queries used ]   [ Generated: 20.04.24, 04:10 GMT ]