A volte quando sto scrivendo codice sperimentale in Mathematica, sono cauto sul fatto che dovrei valutarlo o meno perché potrebbe finire per portare il mio sistema alle sue ginocchia.Valutazione asincrona in Mathematica
Come esempio forzato se si tenta di eseguire il seguente snippet di codice su un computer a 64 bit, molto probabilmente causerà il blocco del sistema dopo un'interruzione completa della memoria.
junk = Table[{x, x}, {10^9}]; (* nom nom nom memory. Please don't run this. *)
Certo, si può semplicemente gettare MemoryConstrained
su di esso e sperare per il meglio, ma a volte non lo vogliono bloccare qualsiasi ulteriore input. A tal fine, il modo in cui pensavo fosse meglio raggiungere una via di mezzo era eseguire la valutazione in un kernel separato.
Quello era decentemente abbastanza facile da fare:
ClearAll[GetAvailableKernel];
GetAvailableKernel[] := Block[{i, kernels},
kernels = Kernels[];
If[[email protected] != 0,
For[i = 1, i <= [email protected], i++,
If[kernels[[i, 1, 2]] > 0, [email protected][[i]]]
]
];
LaunchKernels[1]]
ClearAll[SafeEvaluate];
SetAttributes[SafeEvaluate, HoldFirst];
Options[SafeEvaluate] = {"EvaluationKernel" -> Null,
"ConstrainMemory" -> True, "MaxMemory" -> 2 1024^3};
SafeEvaluate[expr_, OptionsPattern[]] := Block[{evalkernel, result},
If[OptionValue["EvaluationKernel"] != Null,
evalkernel = OptionValue["EvaluationKernel"],
evalkernel = GetAvailableKernel[]
];
result = If[OptionValue["ConstrainMemory"],
With[{memory = OptionValue["MaxMemory"]},
ParallelEvaluate[MemoryConstrained[expr, memory], evalkernel]],
ParallelEvaluate[expr, evalkernel]];
result]
Poi si può solo andare avanti e fare qualcosa sulla falsariga di:
SafeEvaluate[Table[{x, x}, {1024^3}]]
E Mathematica sarebbe tornato con grazia $Aborted
che indica che correva fuori dalla memoria. Valutando in un kernel separato, possiamo inserire il codice sandbox nel proprio kernel parallelo. Se qualcosa va storto, allora il nostro kernel principale non è interessato.
Questo mi porta al mio punto principale: Come posso ottenere la valutazione asincrono all'interno di Mathematica?
Quello che ho ora funziona, ma blocca completamente ogni ulteriore input da parte dell'utente. Non posso semplicemente impostare, dimenticare e controllare più tardi.
Qualche idea?
È elaborato descrivere 'SafeEvaluate' ancora si spende qualche parola sul vostro attuale domanda e sono lasciato a indovinare il suo significato. Stai cercando un modo per valutare un'espressione in una cella, lasciare la valutazione in esecuzione e valutare un'espressione in una seconda cella, ottenendo potenzialmente il risultato prima che la valutazione della prima cella venga completata? –
@ Mr.Wizard Questa è la mia lettura della domanda. Il mio primo pensiero è che questo è impossibile perché qualsiasi valutazione cambierà lo stato del kernel. Quindi due valutazioni parallele cambierebbero in modo similitudinale lo stato del kernel: Mike sta infatti chiedendo il multithreading, con tutte le difficoltà e sottigliezze che fa emergere. (Anche con i kernel paralleli, parte dello stato viene condivisa anche per ottenere i risultati.) Ma poi ho pensato a 'Dynamic [f [i]]', 'Table [Pause [1]; i, {i, 10}] '(provalo --- è come' Monitor'). In realtà questo sta valutando le cose in parallelo, in un singolo kernel. – Szabolcs
@Szabolcs dove dice che vuole una valutazione parallela all'interno di un singolo kernel? –