2015-01-14 4 views
0

Я пытаюсь понять следующий код:UNIX поведение процесса

int main(int argc, char **argv) 
{ 
    int pid1,pid2; 
    if((pid1=fork())<0) 
    { 
     printf("Error bla bla");exit(1); 
    } 
    else printf("A"); 
    if((pid2=fork())<0) 
    { 
     printf("Error bla bla");exit(2); 
    } 

    if(pid1==0)printf("B\n"); 
    if(pid2==0)printf("C\n"); 
    exit(0); 
    return 0; 
} 

выход я получаю выглядит так:

A 
AC 
AB 
AB 
C 

Если я изменяю первый отпечаток на printf("A\n"); выход

A 
C 
A 
B 
B 
C 

Как ведут себя процессы в этой ситуации? Я знаю, что второй fork() выполняется как в родительском процессе, так и в первом дочернем процессе, но почему вывод выглядит так?
Кроме того, почему он печатает последние 3 буквы в этом конкретном порядке?

+1

Возможный дубликат [printf anomaly after "fork()"] (http://stackoverflow.com/questions/2530663/printf-anomaly-after-fork) – pilcrow

+0

Вы могли бы сделать этот код более уродливым? –

+0

@iharob На самом деле я мог, но это было специально написано так, чтобы смутить читателя, что в моем случае –

ответ

0

Возможная причина вашего недоразумения в том, что выход printf("A"); на самом деле не написан на терминале в момент второй вилки. Он находится в буфере памяти и как таковой дублируется вместе с остальной частью процесса.

+0

и почему он печатает «AB AB C» в конце? Не следует ли печатать «AB AB AC»? –

1

Прежде всего, я считаю, что результат этой последовательности не определен правильно - это зависит от разработчика printf() и капризов планирования процесса.

В общем случае printf() накапливает символы в буфере и печатает их, когда захочет, за исключением того, что в общем случае наличие новой строки '\ n' вызывает немедленную печать.

Если процесс вилки с символами, все еще находящимися в буфере printf(), как родительский, так и дочерний процесс будут в конечном итоге напечатать эти символы. Вы разворачиваете два раза, в результате получается 4 процесса. Я назову исходный процесс G (randparent). G создает P (arent) в первой вилке. P имеет pid1 == 0. Затем каждый процесс снова вилки. Предположим, что G создает A (не), а P создает C (hild). A и C имеют pid2 == 0. C также имеет pid1 == 0.

Все они либо напечатали оригинал A \ n, либо имеют A в своем буфере печати.

Те, у кого pid1 == 0, затем printf B \ n. Если есть еще А в буфере, он выходит как АВ \ п Те с ПИД2 == 0, то для печати C \ п

Таким образом, последовательность

G: A(\n) 
P: A(\n)B\n 
A: A(\n)C\n 
C: A(\n)B\nC\n 

Порядок, в котором G, P , A и C не определены. Но вывод любого заданного процесса появляется в том порядке, в котором он выводится printf() d. Он может чередоваться с результатами других процессов.

Если A напечатан с помощью \ n, удалите A (\ n) из всех последовательностей, кроме дедушки.

+0

Stepens Спасибо за ответ, теперь это имеет смысл. У меня остался только один вопрос: почему один процесс обрабатывает только 'C'? Это потому, что буфер решает сам опорожнить или есть какая-то другая причина? –

+0

Я подозреваю, что вы видите процесс C. В первом варианте он будет печатать AB на одной строке, а затем C на другой строке. –

Смежные вопросы