1. 首先,我们来看第一个函数族getpid,这个函数族包括两个函数:
geipid():用来获当前函数的进程号;
getppid():用来获取当前进程的父进程的进程号。
接下来是一个demo,用来获取当前进程及其父进程的进程号:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
void main(void)
{
pid_t ppid, pid;
pid = getpid();
printf("current process id is %d\n", pid);
ppid = getppid();
printf("the parent process of the current process id is %d\n", ppid);
}
编译生成名为getpid的文件,运行结果如下:
2. 接下来我们看下fork函数,fork函数的作用是生成新进程,这个函数的特点在于,如果执行成功,会返回两个值,如果返回的值为0,则是表示返回给生成的子进程;如果返回的值大于0,也就是返回了生成该子进程的父进程的进程号,是返回给父进程的。我们可以根据返回的结果分别写关于子进程和父进程要实现的功能。
这是一个demo,返回-1表示执行该函数失败,返回的值大于0表示是返回给父进程,也即是要运行父进程,返回0则表示运行子进程。由于子进程会继承父进程的资源,因此,这里在父进程中定义一个变量i,观察父子进程的i的特点,还打印了各自的父进程:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
pid_t pid, tmp_pid;
int i = 100;
pid = fork();
if(pid == -1)
{
printf("fork fialed!\n");
}
//返回到父进程
else if(pid)
{
printf("this is parent process!\n");
printf("i = %d!\n", i);
i++;
printf("after i++,i = %d!\n", i);
tmp_pid = getppid();
printf("the parent process pid of this porcess is %d!\n", tmp_pid);
tmp_pid = getpid();
printf("this porcess pid is %d!\n", tmp_pid);
while(1);
}
//返回给子进程
else
{
printf("this is child process!\n");
printf("i = %d!\n", i);
i++;
printf("after i++,i = %d!\n", i);
tmp_pid = getppid();
printf("the parent process pid of this porcess is %d!\n", tmp_pid);
tmp_pid = getpid();
printf("this porcess pid is %d!\n", tmp_pid);
while(1);
}
return ;
}
编译生成名为fork的文件,运行该文件结果如下:
如图所示,父子进程的i互不影响,因此可知,子进程的i与父进程的i在内存的存储不一样,不是同一个地址。
3. 最后,关于进程的一个函数族数execl,它包括6个函数,功能是从当前进程跳转到其他进程,这里只给出execl和execv的demo,其他可以在linux总用man 3 execl详细理解这些函数。
在linux的/bin目录下,有很多可执行文件,例如我们常用的ls,rm命令等,我们就编程实现从当前程序中跳转到这个目录下去执行ls -a命令,demo如下:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *arg[] = {"ls", "-a", NULL};
//子进程1
if(fork() == 0)
{
printf("here is child 1 process, excute execl:\n");
if(execl("/bin/ls", "ls", "-a", NULL) == -1)
{
printf("excute execl failed!\n");
exit(1);
}
}
usleep(2000); //防止进程间相互干扰,加延时错开进程
//子进程2
if(fork() == 0)
{
printf("here is child 2 process, excute execv:\n");
if(execv("/bin/ls", arg) == -1)
{
printf("excute execv failed!\n");
exit(1);
}
}
usleep(2000);
return 0;
}
编译生成名为execlv的文件,运行该文件:
这样,通过execl与execv两种方式调用了/bin中的ls命令查看文件内容了。