Plurk

45 responses to this plurk (Jump to bottom)

  • Sorry
    rand() 同一秒會抓到一樣的值?是 srand() 的關係吧?
  • av.
    樓上正解. 如果要用時間來初使化 seed,就用精準度較高的時間單位,取最後幾位來用
  • av.
    不過我覺得還是乖乖弄懂 Boost.Random 比較有意思
  • jeffhung
    sorry: 不是,是某平台的特徵,其 rand() 的 pseudo algorithm 看起來與目前時間(以秒為單位)相關。 :-P
  • av.
    還有這種事? X-(
  • jeffhung
    待我回想一下細節。
  • jeffhung
    喔,故事是這樣的,既然是 pseudo random,那只要 srand() 的時間差不多(在同一秒),那大家之後所 rand() 得到的 sequence 都會一樣。
  • jeffhung
    所以在很多 processes 甚至跨機器的情況下,大家一起啟動,同時 srand(),然後之後很多事情就會因為 rand() 得到一樣的值而亂了套。
  • jeffhung
    所以不該算是「某平台」的特徵,而是 stdc 的 srand/rand() 的本質就是如此。
  • fr3@K
    那該採用 avhacker 提的解法, 用高 resolution 的時間來當 seed.
  • jeffhung
    freak: 這也可以,不過那時我直接弄了 device_random_generator 來用了。
  • av.
    呼,所以那還好,我還以為真有這種地雷
  • jeffhung
    avhacker: 這其實也算地雷,只是平常不會寫 multi process 甚至跨機器的程式,所以不容易碰到。但碰到時還是會苦很久才能想通原因。
  • Sorry
    如果不是同一個 process 的話,我可能會偷懶用 time() * getpid() 了事(逃)
  • av.
    jeffhung: 也是,但並不是一開始以為的 srand() 本身的雷
  • av.
    sorry: 那就算是同一個 process, 只要是不同 thread 就可以再乖上一個 thread id 了事...
  • jeffhung
    sorry: 同一個 process 用 pthread_self() 也行啊。只是程式寫多了,「慣性」會用 time() 來當 seed,然後就中招了。
  • jeffhung
    avhacker: 是,我亂放的炮害大家誤會,慚愧了。XD
  • av.
    jeffhung: 所以應該把「慣性」改成 Boost.Random
  • jeffhung
    avhacker: Boost 不是大家都有辦法接受的。:-(
  • fr3@K
    jeffhung 補充 - C++ 也不是大家都有辦法接受的
  • Sorry
    好啦好啦我知道你們在說我 (nottalking) (ていうか「對號入座」?)
  • jeffhung
    freak: 怎麼這結論越來越苦了。
  • fr3@K
    sorry 沒在說你啦~~
  • fr3@K
    jeffhung 是還蠻苦的. 給個例子 - 15F 有的 team 不只是 API 要 "C", 連 implementation 都一定要純 "C"
  • 戩天姜
    by definition "random" 可以是同一個值啊 想要不同的值,就 hash 一下?雖然同一秒附近一定 rand 出一樣的序列有嚴重的安全性問題,但不知道這是不是 jeffhung 真正關切的部分?
  • jeffhung
    freak: 不曉得用 llvm 惡搞,把 C++ 轉成 C 可不可以?:-P
  • fr3@K
    :-o 應該不行, 因為產出的 code 還得要過 code review XD
  • jeffhung
    augustinus: 先澄清一點,不是進了 T 社,就會變得更有安全意識。(誤) 改變不是一蹴可及的。XD
  • 戩天姜
    我沒有要戳這個啦 XDDDD
  • jeffhung
    augustinus: 那時的設計是,為了避免系統啟動時,大家一起工作而 congestion,所以會用 random number 大家一起亂暫停一下。結果因為上面那地雷而沒有任何效果。
  • jeffhung
    而且因為 sequence 一樣,所以後面的動作都非常「synchronize」,效率可想而知。XD
  • 戩天姜
    嗯嗯,所以聽起來,用產生 GUID 的套路比較適合?上面有好幾位先進提到了。(我還真多嘴)
  • jeffhung
    Win32 弄 device_random_generator 比較麻煩 (但有 API,沒花時間研究就是了),所以我是在 posix 下用 /dev/random,在 win32 下用 guid_random_generator。
  • jeffhung
    但是 guid_random_generator 也要小心中招,若 guid generator 裡面也採用 pseudo random number 的話...
  • jeffhung
    話說 /dev/random 也是 pseudo 的,然後雖然透過 read() 大家不會都拿到一樣的東西,但 read() 會有 lock...
  • av.
    jeffhung: 其實我在提 Boost.Random 時,就是想順便戳 sorry 啦 XD
  • av.
    jeffhung: 不過這個範例中給的 seed 仍然是以秒為單位來取時間,所以這部分要換掉
  • jeffhung
    avhacker: 我知道。只不過現在還沒差,所以到時候把 typedef 改掉即可。
  • av.
    jeffhung: 我沒用過 Boost.Random, 不過看來它在給 seed 這邊其實也沒比較好用,不知道它的優勢是什麼? 不然還是直接用舊的 c api 算了
  • jeffhung
    avhacker: 優勢在於 plug-n-play,隨時可以換用不同的 generator、distribution。
  • jeffhung
    結果最後讓我覺得 Boost.Random 很複雜的原因是 compile 出一堆 error,細看原來是 -Wshadow 的關係,用 #pragma 把 #include <boost/random.hpp> 包起來就好了。(boost-1.40.0)

Favored by 2 people:

Loading...

Ads