Portál AbcLinuxu, 12. května 2025 01:57
int main(void){ pid_t id; printf("tento text se vypíše dvakrát"); if ((id = fork()) == 0) { /* synovský proces */ putchar('\n'); } else if (id > 0) { /* otcovský proces */ putchar('\n'); } else { perror("fork"); return 1; /* chyba při fork() */ } return 0; }chtel bych vedet, jaktoze se funkce printf provede 2x? moje myslenka je, ze po vytvoreni procesu jak parent tak child pokracuji dale v programu.
fork()
.
FILE*
, prostě nejdřív cachují do paměti a až když tam pošleš znak konce řádku, tak se to odpálí syscallem do kernelu. (Proto taky ty funkce pracují se strukturou FILE a ne rovnou s číselným deskriptorem.)
Takže co se stane - do té cache uložíš ten text, ale ten se ve skutečnosti nikam nevypíše. Pak rozmnožíš ten proces, takže teď každý proces má svou vlastní verzi cache s tím textem. A v obou procesech ji celou odpálíš tím znakem '\n'
.
Je to evidentní z výpisu programu strace -f
.
printf
vložit fflush(stdout);
nebo dát do printf znak konce řádku (\n
).
man stdout
? Číst zrovna tuhle manuálovou stránku by mě na jeho místě asi taky nenapadlo. I když úplně nejlepší je si přečíst všechny manuálový stránky PID User space | Kernel space 1 FILE *stream1 → int fd1 --→ int kfd1Situace po forku:
PID User space | Kernel space 1 FILE *stream1 → int fd1 -+→ int kfd1 2 FILE *stream1 → int fd1 -+Je třeba brát na zřetel, že struct FILE obsahuje vlastní buffer a ukazatel v uživatelském prostoru, tudíž po forku dojde k jeho duplikaci a vzájemné nezávislosti. Naopak int fd v uživ. prostoru je jen číslo, které si jádro spolu s PID přemapuje na interní deskriptor. Buffer file/socket descriptoru je v prostoru jádra a je jenom jeden.
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.