The point of the pipes is to keep them open until the worker owning them dies, originally I was gonna have all the workers talk to each other via the pipes, I've since realised that was a partially bad idea as it would lead to faulty code all over the place, I now have the main thread acting as a middle man where every worker gets a reference to the main thread's pipes and a reference to pipes created for the main thread to talk to them, the main thread is now in charge of memory allocations too so there'll be no need for the risk of a memory managing worker suddenly dieing, at least if the main thread dies then all threads die with it. The main thread also handles the closer of pipes and other worker related stuff linked by the worker structure, although any internal stuff is still the responsibility of the worker itself to cleanup if it needs anything more than a deallocate (which again the main thread can act as a garbage handler for)