I am not an expert on this, but I will still give him a chance.
A GHC (Haskell compiler) can have one or more HECs (a Haskell execution context, also known as a constraint or capability). With the runtime flag +RTS -N <number> or setNumCapabilities you can determine how many of these HECs are available for the program. One HEC is one operating system thread. The runtime scheduler distributes Haskell threads between the HEC.
Using the forkOn function, forkOn can choose which HEC the thread is starting. getNumCapabilities returns the number of capabilities (HEC).
Thread migration means that Haskell threads can be moved (moved) to another HEC. The runtime flag +RTS -qm disables this thread migration.
The forkOn states that
Like forkIO , but it allows you to specify by what possibilities the stream should work. Unlike the forkIO stream, the stream created by forkOn will remain at the same opportunity for the entire life cycle (forkIO streams can be transferred between the possibilities in accordance with the planning policy).
therefore, with forkOn you can select one single HEC in which the thread is running.
Compared to forkIO , which states that
Foreign calls made by this thread are not guaranteed by any particular OS thread; if you need external calls that must be made by a specific OS thread, use forkOS instead.
Now, is the forkOn function and +RTS -qm (thread migration disabled) the same? Probably no. The forkOn user explicitly chooses which HEC the Haskell thread is running on (for example, you can put all Haskell threads in the same HEC). With +RTS -qm and forkIO Haskell threads do not switch between HECs, but there is no way to find out which HEC Haskell thread generated by forkIO ends.
Literature:
source share