Используя вилку с c - PullRequest
       7

Используя вилку с c

3 голосов
/ 19 июня 2011

Это академический вопрос, поэтому причина в том, чтобы понять результат.

У меня есть код:

int main(int argc, char **argv) {
            int k ;
            while(*(++argv)) {
                    k = fork();
                    printf("%s ",*argv);
            }
    return 0;
    }


запустить программу с помощью: prog a b
Выход:

  a b a b a b a b

Почему я получаю этот результат?

Ответы [ 4 ]

2 голосов
/ 19 июня 2011

Как подсказывает Крис Латс в комментариях, вы наблюдаете эффект статического буфера, используемого printf, дублирующегося при вызове fork().Два процесса, созданные первым fork(), не печатают b (как и следовало ожидать, а также, как и в случае принудительного сброса).Они оба печатают a b, потому что у них обоих есть ожидающие, незаполненные a в их соответствующих буферах.

Есть 4 процесса (2 ^ 2, включая исходный), все они действительно печатаются только при выходекогда буфер очищается, и все они имеют a b в соответствующих буферах в то время.

1 голос
/ 19 июня 2011

В начале argv будет указывать на argv[0], которое является именем исполняемого файла, оно увеличивается один раз внутри while(), указывая на argv[1].

Теперь он нажимает fork(), создавая второй поток, начинающийся с той же строки.

Оба потока будут записывать a в свой собственный буфер stdout.

Теперь argv перемещается на 1 символ в обоих случаях (внутри while()), поскольку они, по сути, работают с копиями, если я правильно помню.

Форк в каждом потоке теперь создаст 2 дополнительные копии потока (по одной для каждого существующего потока).

Теперь все 4 экземпляра будут иметь в своем буфере stdout все еще 'a', который копируется (думаю, было бы неплохо, если бы кто-нибудь мог это подтвердить), и их argv указывает на b. Этот тоже написан, так что теперь у нас есть 4 потока, каждый из которых имеет «a b» в своих выходных буферах.

Как только они заканчиваются, их буферы сбрасываются, что приводит к 'a b a b a b a b' (по существу, это 'a b', 'a b', 'a b' и 'a b').

Комментарий Бена можно объяснить покраснением, вызванным разрывом строки.

0 голосов
/ 19 июня 2011

Прежде всего, терминал буферизуется строкой, т. Е. Буферы сбрасываются при обнаружении новой строки.Если вы поместите новую строку в printf (), результаты изменятся.Однако, если вы пишете в файл, который полностью буферизован, в выходных данных не будет изменений, даже если вы добавите новую строку в printf ().

После первого вызова fork (), P (parent) имеет «a», а C1 также имеет «a».(C для потомка).

Затем, после второго вызова fork, создаются два новых потомка C2 и C3.Буферы процесса также копируются, поэтому C2 и C3 теперь также содержат «a».После вызова printf () все процессы содержат «ab» в своих буферах.И когда они выходят, их буферы сбрасываются, и, следовательно, вывод.

0 голосов
/ 19 июня 2011

Я не знаю о «форке», но могу сказать вам, что на второй итерации цикла вы получаете доступ к бессмысленной области памяти. Это, безусловно, возвращает искаженные, бессмысленные результаты и, что еще хуже, может нарушить выполнение программы.

Вы, конечно, должны делать что-то вроде

while ((--argc) >= 0) { (...) }

, если вам не нужно знать исходное значение argc после цикла, или же

int i = 0;
while (i++ < argc) { (...) }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...