父进程看似先于子进程完成,为何仍能打印管道输出的Hello world?
关于管道与父子进程同步的问题解答
你看到的in parent先打印,只是父进程被操作系统优先调度执行,先跑完了printf("in parent\n"),但接下来的read(fildes[0], buff, BSIZE)会阻塞——这是管道read()的核心特性:当管道内无数据,但仍有写端处于打开状态时,read()会暂停父进程的执行,直到有数据写入管道,或者所有写端被关闭。
所以父进程并没有“先执行完成”,它只是卡在read()调用处等待数据。此时操作系统会调度子进程运行,子进程打印in child后将数据写入管道,完成写入操作后,父进程的read()被唤醒,读取到管道中的"Hello world\n",接着执行后续的printf输出内容。
是否需要添加wait()调用?
这个例子里不需要。因为read()已经完成了父子进程的同步:父进程必须等待子进程写入数据才能继续执行。如果你的场景需要等待子进程完全退出(比如子进程还有其他耗时操作),才需要调用wait()或waitpid()来同步,但这个例子里子进程写完数据就退出了,read()已经足够让父进程等待子进程完成写入动作。
移除close()调用为何仍能正常工作?
虽然能运行,但这不是规范写法。管道的两端应该在不需要时及时关闭:
- 子进程关闭读端(
fildes[0])、父进程关闭写端(fildes[1]),是为了避免管道的引用计数异常。比如如果父进程没关闭写端,子进程退出后,管道的写端仍有父进程的引用,此时若父进程后续不写入数据,read()会一直阻塞到所有写端关闭才返回0。这个例子里因为子进程已经写入了数据,父进程读到数据就继续执行,所以没暴露问题,但养成关闭无用管道端的习惯很重要,能避免隐蔽的资源泄漏或死锁问题。
内容的提问来源于stack exchange,提问作者learning c
相关产品推荐
相关产品推荐

