Не существует переносимого способа реализации варианта fork
, который сохраняет все потоки, используя интерфейсы, предоставляемые POSIX.В некоторых системах, таких как Linux, вы можете реализовать крайне непереносимую и очень хрупкую версию:
, используя ptrace
для отслеживания всех потоков (для их остановки), затемсоздание новых потоков ядра в дочернем процессе для дублирования каждого потока в родительском процессе и присвоение им исходных адресов стека, указателей инструкций, значений регистров и т. д. Вам также необходимо исправить дескрипторы потоков, чтобы узнать их новые идентификаторы потоков пространства ядра,и вам следует избегать условий гонки в этом случае, если поток находился в середине запроса своего идентификатора потока.
с использованием vfork
, за которым следует SIGSTOP
, чтобы остановить родительский процесси дайте себе шанс воссоздать его состояние потока без каких-либо изменений под вас.Это кажется возможным, но достаточно трудным, я бы почувствовал головную боль, пытаясь углубиться в детали, я думаю ...
(недавно добавлено) перехватывает каждый поток в обработчиках сигналов перед разветвлением и сохраняетucontext_t
аргумент обработчику сигнала.Затем выполните разветвление и создайте новые потоки ядра (используя clone
), попросите их сигнализировать себя, а затем перезаписать обработчик сигнала ucontext_t
, чтобы обработчик сигнала вернулся обратно в контекст исходного потока, который вы пытаетесь продублировать.Конечно, все это потребовало бы очень умной синхронизации ...
В качестве альтернативы, вы могли бы искать основанный на ядре подход "спящего режима" к контрольным точкам, который не был бы таким хакерским ...