Иногда, когда я пишу экспериментальный код в Mathematica, я опасаюсь, стоит ли мне его оценивать или нет, потому что это может в конечном итоге поставить мою систему на колени.
В качестве надуманного примера, если вы попытаетесь запустить следующий фрагмент кода на 64-разрядной машине, это, скорее всего, приведет к полной остановке системы после того, как она израсходует всю вашу память.
junk = Table[{x, x}, {10^9}]; (* nom nom nom memory. Please don't run this. *)
Конечно, вы можете просто добавить MemoryConstrained
и надеяться на лучшее, но иногда вы не хотите, чтобы это блокировало дальнейший ввод. В связи с этим я подумал, что для достижения среднего уровня лучше всего было бы выполнить оценку в отдельном ядре.
Это было достаточно легко сделать:
ClearAll[GetAvailableKernel];
GetAvailableKernel[] := Block[{i, kernels},
kernels = Kernels[];
If[Length@kernels != 0,
For[i = 1, i <= Length@kernels, i++,
If[kernels[[i, 1, 2]] > 0, Return@kernels[[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]
Тогда вы можете просто пойти дальше и сделать что-то вроде:
SafeEvaluate[Table[{x, x}, {1024^3}]]
И Математика грациозно вернет $Aborted
, сообщая вам, что у него кончилась память. Оценивая в отдельном ядре, мы можем поместить код в песочницу в его собственное параллельное ядро Если что-то пойдет не так, наше основное ядро не будет затронуто.
Это подводит меня к моей главной мысли: Как мне достичь асинхронной оценки в Mathematica?
То, что у меня есть сейчас, работает, но оно полностью блокирует дальнейший ввод пользователя. Я не могу просто установить, забыть и проверить позже.
Есть мысли?