Does ets:select/2 block the VM?
Tue Mar 4 09:42:09 CET 2003
Answer from Patrik Nyblom:
Shawn Pearce <> writes:
> I'm wondering about the implementation of ets:select/2.
> If I match against a table with 200k records it takes nearly 1 second to
> complete on my system. I think I'm ok with this performance wise, but
> I can't have the ets:select/2 call block the entire emulator, other traffic
> still needs to be executed and processed in other processes.
It will be. The process will be rescheduled several times during the
'select', precisely because we cannot have it blocking the emulator.
> An informal test where I spawn up a background process and have it
> use io:format/2 every 10 milliseconds to print a message seems to run
> perfectly fine while a 1 second ets:select/2 runs in another process.
> I'm assuming thus that the Erlang system authors have thought about this
> and have ensured that it doesn't become a problem. :-)
Oh, yes :-)
> Also, the documentation is vague as to what happens if the table owner
> modifies a protected ets table using insert or delete while other
> processes are using ets:select/2 or ets:select/3 (select with
> a limit and continuation). Is it safe to perform this, or does
> the reader process have to use ets:safe_fixtable/2 ?
Sorry for the vague documentation. What should have been in the doc is
It is "safe" to use select/2 (or match/match_object) on a table while
another process is updating it. It will however not be a real transaction.
The table is fixed during the select-operation, but if an object appears
in the table it depends on the hash value (in the set/bag/duplicate bag
case) if the simultaneous select will see it, i.e. if the select has
already traversed the hash bucket where the new object is inserted, it
wont see it and vice versa. In the ordered set case, the effect is rougly
the same, but it depends on the key value itselt if it will be seen (the
In the case of select/3, the "automatic fixation" of the table cannot be
done (cause ets does not know when you're done traversing), so you have to
use safe_fixtable/2 to achieve the same effect. If you use ordered_set,
the safe_fixtable/2 is a noop however, it simply isn't needed for trees,
so strictly speeking it isn't really needed for that table type, but it
costs very little to use it anyway.
More information about the erlang-questions