Какова самая близкая вещь, которую Windows должен разветвить ()?

Я предполагаю, что вопрос говорит все это.

Я хочу разветвиться в Windows. Какова самая подобная операция и как я использую ее.

115
задан lornova 2 October 2019 в 11:21
поделиться

7 ответов

Cygwin имеет полнофункциональную fork () в Windows. Таким образом, если использование Cygwin для вас приемлемо, тогда проблема решена, если производительность не является проблемой.

В противном случае вы можете посмотреть, как Cygwin реализует fork (). Из довольно старой архитектуры Cygwin doc :

5.6. Создание процесса Вызов вилки в Cygwin особенно интересен потому что он плохо отображается поверх API Win32. Это делает его очень сложно реализовать правильно. В настоящее время вилка Cygwin является реализация без копирования при записи похоже на то, что было в начале разновидности UNIX.

Первое, что происходит, когда родительский процесс порождает дочерний процесс в том, что родитель инициализирует пробел в таблице процессов Cygwin для ребенок. Затем он создает приостановленный дочерний процесс, использующий Win32 CreateProcess вызов. Далее родитель процесс вызывает setjmp, чтобы сохранить свой контекст и устанавливает указатель на это в общая область памяти Cygwin (общая среди всех задач Cygwin). Затем он заполняет в дочерних разделах .data и .bss путем копирования из собственного адресного пространства на адрес отстраненного ребенка пространство. После адресного пространства ребенка инициализируется, потомок запускается, пока родитель ждет мьютекса. Ребенок обнаруживает, что он был разветвлен и длинные прыжки с использованием сохраненного буфера перехода. Затем ребенок устанавливает мьютекс родитель ждет и блокирует еще один мьютекс. Это сигнал для родитель, чтобы скопировать свой стек и кучу в ребенка, после чего освобождает мьютекс, которым является ребенок ждет и возвращается с развилки вызов. Наконец ребенок просыпается от блокировка на последнем мьютексе, воссоздает любые области с отображением памяти, переданные ему через общую зону и возвращается из сам форк.

Пока у нас есть идеи, как ускорить реализацию форка на уменьшение количества контекста переключается между родителем и потомком процесс, вилка почти наверняка всегда быть неэффективным под Win32. К счастью, в большинстве случаев создать семейство вызовов, предоставляемых Cygwin можно заменить на пара fork / exec с небольшим усилие. Эти звонки четко отображаются наверху API Win32. В результате они намного эффективнее. Изменение программа драйвера компилятора для вызова спавн вместо вилки был тривиальным изменение и усиление компиляции скорости от двадцати до тридцати процентов в наши тесты.

Однако spawn и exec представляют свои собственный набор трудностей. Потому что там невозможно выполнить фактическое выполнение под Win32, Cygwin должен изобрести свой собственный Идентификаторы процесса (PID). В результате, когда процесс выполняет несколько exec звонков, будет несколько окон PID, связанные с одним Cygwin PID. В некоторых случаях заглушки каждого из эти процессы Win32 могут задерживаться, жду их exec'd Cygwin

Похоже, много работы, не так ли? И да, это медленно.

РЕДАКТИРОВАТЬ: документ устарел, пожалуйста, посмотрите этот отличный ответ для обновления

80
ответ дан 24 November 2019 в 02:25
поделиться

Я, конечно, не знаю подробностей об этом, потому что я никогда этого не делал, но собственный NT API имеет возможность разветвлять процесс (подсистема POSIX в Windows нуждается в этой возможности - Я не уверен, поддерживается ли вообще подсистема POSIX).

Поиск по запросу ZwCreateProcess () должен дать вам некоторые дополнительные сведения - например этот фрагмент информации от Максима Шатских :

Самый важный параметр здесь - SectionHandle. Если этот параметр равно NULL, ядро ​​будет форкнуть текущий процесс. В противном случае это параметр должен быть дескриптором объекта раздела SEC_IMAGE, созданного на EXE-файл перед вызовом ZwCreateProcess ().

Хотя обратите внимание, что Коринна Виншен указывает, что Cygwin, обнаруженный с помощью ZwCreateProcess (), все еще ненадежен :

Икер Арисменди писал:

> Потому что проект Cygwin полагался исключительно на Win32 API его вилка
> реализация не является COW и неэффективна в тех случаях, когда форк
> не следует за exec. Это тоже довольно сложно. Смотрите здесь (раздел
> 5.6) для подробностей:
> 
> http://www.redhat.com/support/wpapers/cygnus/cygnus_cygwin/architecture.html

Этот документ довольно старый, лет 10 или около того. Пока мы все еще используем Win32 вызывает эмуляцию fork, метод заметно изменился. В частности, мы не создаем дочерний процесс в приостановленном состоянии. больше, если конкретные данные не нуждаются в особой обработке в родитель, прежде чем они будут скопированы в дочерний. В текущей 1.5.25 освободить единственный случай для подвешенного ребенка - открытые розетки в родитель. Предстоящий выпуск 1.7.0 вообще не будет приостановлен.

Одной из причин не использовать ZwCreateProcess было то, что до версии 1.5.25 выпуске мы по-прежнему поддерживаем пользователей Windows 9x. Однако два попытки использовать ZwCreateProcess в системах на базе NT ни к чему не привели. причина или другая.

Было бы здорово, если бы эта штука была лучше или вообще задокументированы, особенно пара структур данных и способы подключения процесс в подсистему. Хотя вилка не является концепцией Win32, я не вижу, что было бы плохо упростить реализацию форка.

60
ответ дан 24 November 2019 в 02:25
поделиться

Ну, в Windows нет ничего подобного. Тем более, что fork можно использовать для концептуального создания потока или процесса в * nix.

Итак, я должен сказать:

CreateProcess () / CreateProcessEx ()

и

CreateThread () (я слышал, что для приложений C _beginthreadex () лучше).

35
ответ дан 24 November 2019 в 02:25
поделиться

До того, как Microsoft представила свою новую опцию «Подсистема Linux для Windows», CreateProcess () была наиболее близкой к Windows fork () , но Windows требует, чтобы вы указали исполняемый файл для запуска в этом процессе.

Создание процесса в UNIX сильно отличается от Windows. Его вызов fork () практически полностью дублирует текущий процесс, каждый в своем собственном адресном пространстве, и продолжает выполнять их отдельно. Хотя сами процессы разные, они по-прежнему выполняют одну и ту же программу . См. здесь для хорошего обзора модели fork / exec .

Возвращаясь назад,

6
ответ дан 24 November 2019 в 02:25
поделиться

В следующем документе представлена ​​некоторая информация о переносе кода с UNIX на Win32: https://msdn.microsoft.com/en-us/library/y23kc048.aspx

Среди прочего, это указывает на то, что модель процесса сильно различается между двумя системами, и рекомендует рассмотреть CreateProcess и CreateThread, где fork () - подобное поведение не требуется.

6
ответ дан 24 November 2019 в 02:25
поделиться

Лучшими вариантами являются CreateProcess () или CreateThread () . Дополнительную информацию о переносе можно найти здесь .

2
ответ дан 24 November 2019 в 02:25
поделиться

Нет простого способа эмулировать fork () в Windows.

Я предлагаю вам использовать вместо этого потоки.

2
ответ дан 24 November 2019 в 02:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: