форк начинает выполнять форму где? - PullRequest
0 голосов
/ 05 марта 2011

На мой предыдущий вопрос об ошибке сегментации я получил очень полезные ответы. Спасибо всем, кто ответил.

#include<stdio.h>
main()
{
 printf("hello");
int pid = fork();
wait(NULL);
}

output: hellohello.

В этом процессе запускается дочерний процесссформировать начало.Если я не ошибаюсь, то как работает программа, если я поставлю sem_open перед fork () (см. Ответы на вопросы: prev)

Мне нужно четкое объяснение ошибки сегментации, которая случается иногда и не всегда,И почему не всегда ... Если есть какая-то ошибка в кодировании, то это должно происходить всегда правильно ...?

Ответы [ 2 ]

6 голосов
/ 05 марта 2011

fork создает клон вашего процесса. Концептуально говоря, все состояние родителя также заканчивается у ребенка. Это включает в себя:

  • Регистры процессора (включая указатель инструкций, который определяет, где в коде находится ваша программа)
  • Память (в качестве оптимизации ваше ядро, скорее всего, будет помечать все страницы как копируемые при записи, но, говоря семантически, это должно совпадать с копированием всей памяти.)
  • Файловые дескрипторы

Следовательно ... Ваша программа не будет "запускаться" откуда-либо ... Все состояние, которое вы имели при вызове fork, будет распространяться на ребенка. Ребенок вернется с fork точно так же, как родитель.

Что касается того, что вы можете сделать после разветвления ... Я не уверен в том, что говорит POSIX, но я бы не стал полагаться на то, что семафоры делают правильные вещи после fork. Вам может понадобиться семафор внутри процесса (см. man sem_open или параметр pshared sem_init). По моему опыту, кросс-процессные семафоры не очень хорошо поддерживаются в свободных ОС типа Unix ... (Пример: некоторые BSD всегда терпят неудачу с ENOSYS, если вы когда-либо пытаетесь его создать.)

@ GregS упоминает дублированные строки "привет" после разветвления. Он прав, говоря, что stdio (то есть FILE*) будет буферизоваться в памяти пространства пользователя, и что fork приводит к буферизации строки в двух процессах. Возможно, вы захотите позвонить fflush(stdout); fflush(stderr); и сбросить любые другие важные ручки FILE* до fork.

3 голосов
/ 05 марта 2011

Нет, он начинается с fork(), который возвращает 0 в дочернем элементе или идентификатор дочернего процесса в родительском элементе.

Вы видите «привет» дважды, потому что стандартный вывод буферизован и не имеетна самом деле было написано в точке разветвления.И родитель, и потомок фактически пишут буферизованный вывод.Если вы fflush(stdout); после printf(), вы должны увидеть его только один раз.

...