What happens when the application starts?
When the application starts, the dispenser initializes itself. You can do this the first time you call your allocator, if you want.
And how does the distributor know that heaps have already been created?
I am not sure that I am following this question. If you are talking about heaps that are managed by code that uses this same allocator, it discovers that it creates tracking records when it creates heaps. If you are talking about heaps in other processes or creating other allocators, it doesn't matter, since he cannot use these heaps anyway.
How does the dispenser create, save, and destroy (when the application closes) heaps?
Typically, you have a low-level and high-level dispenser. The low-level allocator simply receives raw chunks of memory from the operating system. The exact mechanism is platform specific. The high-level allocator manages the heaps, and it receives memory for storing heap structures from the low-level allocator.
When a function is called, how do I know which thread (or processor) it is running on?
You can find out which thread is associated with the data depending on the thread, or by calling the "get thread ID" function for a specific platform. As for the processor, it is very specific to the platform, and by the time it is received, the information may be outdated. Most platforms have this feature - just remember that you can only use it as an optimization (to reduce lock conflict or improve cache attack speed). Critically, you cannot use it to bypass a lock, because a thread can move from one processor to another at any time.
Honestly, a memory allocation that provides good performance and is portable across all platforms is indeed a case of heavy magic. If you are not an expert in this field, it is unlikely that you will be able to develop a distributor that provides the performance and stability needed for a production application.