linux中进程的相关函数:fork(),vfork(),getpid(),getppid(),wait().
1.常用的函数:
这些函数是进程中用到的最基本的函数一定要好好掌握。
fork()函数,开辟内存,拷贝父进程的资源(数据段,代码段),新建一个子进程。
vfork()函数,保证了子进程先运行,在exec 和 exit 执行之前与父进程共享数据段,如果在子进程调用这两个函数之前,依赖于父进程的进一步动作,将会造成死锁。
getpid()函数,获取当前进程的pid号。
getppid()函数,获取当前进程父进程的pid号。
wait()函数,用在父进程中,用于等待自己的直系子进程的结束。(必须是等待由自己创建的直系子进程)。
2.进程运行的状态:
进程是程序的执行过程,根据它的生命周期可以划分成3种状态:执行态、就绪态、等待态。它们之间的转换关系图如下图所示:
3.Linux下的进程结构
Linux系统是一个多进程的系统,它的进程之间具有并行性、互不干扰等特点。也就是说进程之间是分离的任务,拥有各自的权利和义务。每一个进程都运行在各自独立的虚拟地址空间,因此,即使一个进程发生异常,它也不会影响到系统中的其他进程。Linux中的进程包含3个段,分别为"数据段"、“代码段”和“堆栈段”。
- 数据段存放的是全局变量、常数以及动态数据分配的数据空间(如malloc函数取得的空间)等
- 代码段存放的是程序代码的数据。
- 堆栈段存放的是子程序的返回地址、子程序的参数以及程序的局部变量。
#include<stdio.h>
#include<unistd.h>
int main()
{
pid_t pid = fork();
if(pid == 0)
{
printf("this is child.\n");
}
else if(pid > 0)
{
printf("this is parent.\n");
}
else
{
perror("fork.");
}
return 0;
}

这是Linux的C编程中,用fork()函数创建子进程的一个过程。从执行的结果来看,仿佛是先执行父进程再执行子进程,父进程的优先级能比子进程稍微高一些。fork()函数是一次调用,多次返回。如果创建失败将-1返回给父进程;成功的话将子进程的pid返回给父进程;将0返回给子进程(可以这样理解子进程并没有自己的“儿子”,所以收到的返回值是0)。
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{ int count = 0;
pid_t pid = vfork();
if(pid == 0)
{
printf("this is child.pid = %d\n",getpid());
++count;
printf("count = %d\n",count);
_exit(0);
}
else if(pid > 0)
{
printf("this is parent.pid = %d\n",getpid());
++count;
printf("count = %d\n",count);
}
else
{
perror("fork.");
}
return 0;
}

这是vfork()函数,从运行结果分析:vfork()函数保证子进程先执行,在执行exec和exit这两个函数之前,与父进程共享数据段,通过++count,将共享的count变为1,在执行完_exit之后,再执行父进程,父进程通过++count将count变量变为2。
#include<stdio.h>
#include<unistd.h>
int main()
{
pid_t pid = fork();
if(pid == 0)
{
pid_t pid1;
pid1 = fork();
if(pid1 == 0)//父进程的孙子进程
{
printf("pid1 = %d\n",getpid());
sleep(10);
printf("pid1 end.\n");
}
else if(pid1 > 0)//父进程创建的第一个子进程
{
printf("pid0 = %d\n",getpid());
sleep(3);
printf("pid0 end.\n");
}
}
else if(pid > 0)
{
pid_t pid2;
pid2 = fork();
if(pid2 == 0)//父进程创建的第二个子进程
{
printf("pid2 = %d\n",getpid());
sleep(2);
printf("pid2 end.\n");
}
else if(pid2 > 0)//父进程
{
int status;
printf("Parent process wait......\n");
pid_t pid_ret = wait(&status);//wait()函数可以返回等到的子进程的pid号
printf("pid_ret = %d\n",pid_ret);
}
}
else
{
perror("fork.");
}
return 0;
}
上面的程序是为了验证父进程中的wait()函数究竟在等待什么?由上面的注释我们可以很清晰的明白创建的进程的结构。通过调整子进程睡眠的时间,我们可以构造各种子进程结束的情况。由此得到wait()函数等的只能是直系子进程。验证结果较为繁琐,就不贴图了。这充分说明“谁的爱人,谁来等!”PS: 父进程等的是pid2。