2013-08-13 3 views
30

Ho un programma server che seleziona in modo casuale 10 da un gruppo di peer di rete per eseguire un'attività. Il codice che genera gli indici casuali dei coetanei è la seguente:I numeri casuali Haskell iniziano improvvisamente a "convergere" dopo mesi di esecuzione

indices = let index = getStdRandom $ randomR (0, number_of_peers - 1) 
      in sequence $ replicate 10 index 

Il programma è in corso da mesi, generando migliaia di `indici ogni giorno, e sta funzionando benissimo fino a ieri, quando ho notato che qualcosa è andato storto: i numeri casuali generati sembrano "convergere" in alcuni valori ripetuti (il risultato è che i corrispondenti peer di rete sono pesantemente caricati).

vedere il cambiamento, sotto è dal server log di pochi giorni fa:

peers selected: [55,47,80,74,183,85,04,33,72,58] 

e il registro da oggi (come si può vedere, scrutare 53, 37 e 195 sono ripetutamente selezionati):

peers selected: [53,53,37,37,37,37,195,195,195,21] 

Il programma è in esecuzione su una versione x86_64 di Ubuntu 10.10.

+0

credo che il modo corretto di passare generando più numeri casuali sia quello di alimentare il seme di uno nel prossimo calcolo casuale, o almeno di usare 'newStdGen' (che è ancora un po 'incerto). –

+0

Nel caso di afferrare un nuovo seme ogni volta, lasci le cose al sistema/ambiente. Ma passare il seme ogni volta significa che fai affidamento sulle librerie di haskell e sulla matematica al loro interno. A questo punto, nessuna delle effettive risorse crittografiche è gestita da haskell. questo problema non è un problema di haskell, quindi, e più di un problema di ubuntu. –

+4

@JustinL. Secondo il doc, il generatore casuale usato da getStdRandom è ** single, implicito e globale **, e ogni chiamata a getStdRandom lo preleva, lo usa, lo aggiorna e lo restituisce, quindi suppongo che sia equivalente al passaggio esplicito . Ma penso che questo sia un problema con Linux. – Aufheben

risposta

10

Dopo le indagini questo risulta essere un mio bug imbarazzante: l'utente root su questo server ha un limite di file aperti massimi di 1024, che è inaspettatamente basso (ma ho sentito che questo è il default su Ubuntu) . Quando il programma server ha troppi socket aperti, parte del sistema inizia a rifiutare i peer, rendendo il loro stato 'inattivo'. Gli "indici" effettivi sono:

indices = let index = getStdRandom $ randomR (0, M.size active - 1) in 
       sequence $ replicate (n * 2) index 

Mi dispiace se questa domanda causa problemi o confusione. Proverò a postare con maggiore prudenza la prossima volta.