Linux下fork()创建进程

这里写自定义目录标题

  • 进程
    • 小概念
    • 示例1
    • 示例2

进程

进程既是一个独立拥有资源的基本单位,又是一个独立调度的基本单位。一个进程实体由若干个区(段)组成,包括程序区、数据区、栈区、共享存储区等。每个进程配置有唯一的进程控制块PCB,用于控制和管理进程。

小概念

进程,主要包含三个元素:
1.一个可以执行的程序;
2.和该进程相关联的全部数据(包括变量,内存空间,缓冲区等等);
3.程序的执行上下文(execution context)。
进程标识(PID):即进程id,每个进程的id都是唯一的。
getpid():获取当前进程ID。
getppid():获取父进程ID。
pid_t是C语言中用户自定义类型在sys/types.h中定义,例二会用到。

typedef int pid_t;

fork()函数:

          pid= fork();

1、c程序一开始,就会产生 一个进程,当这个进程执行到fork()的时候,会创建一个子进程。
2、父子进程并发运行,子进程复制父进程的如下属性代码段、数据段的内容,父子进程拥有相同的代码和数据,但不复制进程的PID属性
3、fork()是创建进程函数。此时父进程和子进程是共存的,它们俩会一起向下执行c程序的代码.
fork返回值 pid= fork() < 0,进程创建失败;
pid= fork() == 0,表示子进程;
pid= fork() > 0,表示父进程;

父进程从fork返回处继续执行,在父进程中,fork返回子进程PID
子进程从fork返回处开始执行,在子进程中,fork返回0

4、这里特别注意:
子进程创建成功后,fork是返回两个值,一个代表父进程,一个代表子进程:代表父进程的值是一串数字,这串数字是子进程的ID(地址);一个代表子进程,值为0。

示例1

题目:Ubuntu下调用fork()函数创建子进程

代码如下:

#include
#include /*对POSIX 操作系统 API 的访问功能的头文件*/
#include/*是Unix/Linux系统的基本系统数据类型的头文件,含有size_t,time_t,pid_t等类。*/
int main()
{
 int pid;
 printf("The pid before fork:%d\n",getpid());
 pid= fork(); /*创建子进程*/
 if(pid<0)  /* 错误发生*/
 {
 printf("error!!!\n");
 return 1;
 }else if(pid ==0) /* 子进程*/
 {
 printf("I am the child,my pid is:%d\n ",getpid());
 }else  /* pid>1父进程*/
 { 
 printf("I am the father,my pid is:%d\n",getpid()); 
 printf("Hello Fork!\n");
 return 0;
 }

结果:
Linux下fork()创建进程_第1张图片
Linux下fork()创建进程_第2张图片
分析
1.fork的两次返回,指的是子进程和父进程各返回了一个值。
这里要强调的是,它不是返回了两个值,而是返回了两次,一次返回一个值,所以它还是符合函数返回值的特性—只能返回一个值。
2.fork函数的子进程与父进程之间的执行顺序不确定,及每次运行之后的结果顺序可能不同。因此我们新创建的进程总要调用exec(),所以,内核往往先执行新创建的子进程。

示例2

题目:Ubuntu下进程创建实验,理解exec命令对进程控制块的操作。
代码如下
fprintf 函数的功能是:格式化输出数据到流,这个流并没有特指是文件流.
关于 stdin、stdout、stderr 的说明如下:
默认情况下,标准输入从键盘读取,同时标准输出和标准错误会打印到屏幕。
wait(NULL);等待子进程退出
execlp():会从PATH 环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的argv[0]、argv[1]……,最后一个参数必须用空指针(NULL)作结束。如果函数调用成功,进程自己的执行代码就会变成加载程序的代码,execlp()后边的代码也就不会执行了.

#include 
#include 
int main()
{
pid_t pid; 
/* fork a child process */
pid = fork();
if (pid < 0) { /* error occurred */
fprintf(stderr, "Fork Failed");
return 1;
}
else if (pid == 0) { /* child process */
execlp("/bin/ls","ls",NULL);
}
else { /* parent process */
/* parent will wait for the child to complete */
wait(NULL);
printf("Child Complete");
}
return 0;
}

结果:
.Linux下fork()创建进程_第3张图片
结果有点问题,子进程好像没有执行,但和同学代码什么的都一样,不太清楚原因,有知道的朋友可以留言讨论。

你可能感兴趣的:(linux,操作系统)