C语言fork函数
函数签名: pid_t fork(void);
子进程中返回0,父进程中返回子进程ID,出错返回-1
函数签名:
pid_t waitpid(pid_t pid,int* stat_loc,int options);
函数签名:
pid_t getpid(void);
pid_t getppid(void); //用于获取父(parent)进程的pid
函数签名:
void eixt(int status);
示例1 创建一个这样的进程
创建一个如下的
c语言 fork() 能不能解释一下程序为什么会得到这两种结果,怎么算出来的
对于第一个程序,首先父进程会创建5个子进程;
然后,因为父子进程共用代码段,于是子进程也会把for循环执行4次,每个子进程继续4个子进程;
最后,子进程创建的子进程,依然会继续创建3个子进程。 所以,你自己在纸上画一下这个父子关系,实际上是一颗进程树,你就明白了。第二个程序同理,只是进程的代码段不同,所以得到的结果不同而已。
因fork会返回2个值,返回非零,是创建的子进程号,此时在父进程中;返回零是在子进程中;
所以,一般来说:应该根据fork的返回值来使代码选择不同的执行路径,简单举例:
if (fork() !=0 )
{
parent process do something
}
else
{
child process do something
}
C语言中的fork和pipe的问题
fork —– fork —– fork
加入进程A fork出了进程B,然后进程B又fork出了进程C,进程C又fork出了进程D
pipe是管道,只有一个入口,一个出口。可以把入口和出口分别放到父子进程中。
父进程负责读,子进程负责写。或者子进程读,父进程写。
你的例子里,在进程A里创建管道PipeA,然后fork出进程B。进程AB之间使用PipeA通信。
进程B再创建PipeB,然后进程BC之间使用PipeB通信。
进程C再创建PipeC,然后进程CD之间使用PipeC通信。
如果想把进程A的数据传递给进程D,那么应该:进程A向PipeA写入数据,进程B从PipeA中读取数据,然后再写入PipeB,进程C从PipeB中读取数据,然后再写入PipeC,进程D从PipeC中读取数据
fork函数是什么?
Fork:创建一个和当前进程映像一样的进程可以通过fork( )系统调用:
#include sys/types.h
#include unistd.h
pid_t fork(void);
成功调用fork( )会创建一个新的进程,它几乎与调用fork( )的进程一模一样,这两个进程都会继续运行。在子进程中,成功的fork( )调用会返回0。在父进程中fork( )返回子进程的pid。如果出现错误,fork( )返回一个负值。
最常见的fork( )用法是创建一个新的进程,然后使用exec( )载入二进制映像,替换当前进程的映像。这种情况下,派生(fork)了新的进程,而这个子进程会执行一个新的二进制可执行文件的映像。这种“派生加执行”的方式是很常见的。
在早期的Unix系统中,创建进程比较原始。当调用fork时,内核会把所有的内部数据结构复制一份,复制进程的页表项,然后把父进程的地址空间中的内容逐页的复制到子进程的地址空间中。但从内核角度来说,逐页的复制方式是十分耗时的。现代的Unix系统采取了更多的优化,例如Linux,采用了写时复制的方法,而不是对父进程空间进程整体复制。
编写一C语言程序,实现在程序运行时通过系统调用fork( )创建两个子进程
#include stdio.h
int main()
{
int pid;
/*这里创建了一个子进程1*/
pid=fork();
if(pid==0)
printf(“I am son,my pid is %d.\n”,getpid());
else if(pid0)
{
/*从子进程1返回到父进程时,再创建子进程2。*/
printf(“I’m father ,my pid is %d.\n”,getpid());
pid=fork();
if(pid==0)
printf(“I’m daughter process,my pid is %d.\n”,getpid());
else if(pid0)
printf(“I’m father process,my pid is %d.\n”,getpid());
else
printf(“fork() error.\n”);
}
else printf(“fork() error.\n”);
}