Threading
A solver may search on several threads (see the threads option).
The protocol fixes how that interacts with the callbacks and the model passed to fznso_<name>_solver_run.
Only two of the three rules below place any obligation on the application.
on_solution and on_message are called serially
Section titled “on_solution and on_message are called serially”Never two at once, and never one while the other runs, but either may be called from any thread — the worker that found a solution, say — as long as each call happens-before the next.
An application therefore never has to make these callbacks safe to call concurrently. If it wants to process solutions in parallel, it does so behind a serial callback, for example by pushing to a queue.
Serialisation fixes the order solutions arrive in, but does not by itself make that order meaningful: reporting improving solutions in improving order is the solver’s obligation, and serial delivery is what preserves it once several workers are producing them.
The model may be read concurrently
Section titled “The model may be read concurrently”The model is a read-only view for the duration of the call, and a parallel solver may query it from any number of threads at once.
An application must therefore make its model safe for concurrent reads.
In practice the FznsoModelMethods callbacks must not mutate anything observable: no lazily-filled caches without synchronisation, no returning pointers into a buffer that a later call overwrites.
should_stop may be called concurrently
Section titled “should_stop may be called concurrently”From any thread, and even while on_solution or on_message is running, every worker may poll it independently.
It is the other callback an application must make thread-safe, which the usual implementation — reading an atomic flag — already is.
Summary
Section titled “Summary”| Called from | Concurrently? | Application must synchronise? | |
|---|---|---|---|
on_solution | any thread | no, serial with on_message | no |
on_message | any thread | no, serial with on_solution | no |
| model accessors | any thread | yes | yes |
should_stop | any thread | yes, incl. during the other callbacks | yes |