【Linux学习】 进程管理 fork系统调用 创建子进程 阻塞父进程

目录

前言

一、进程

进程ID

Linux下的进程结构

进程状态

init进程

二、fork系统调用

fork相关头文件

fork函数原型

Linux手册查看

fork创建代码示例

运行效果

注意点


前言

本文主要学习Linux内核编程,结合Visual Studio 2019进行跨平台编程,内容包括进程相关知识介绍,fork系统调用相关知识

一、进程

首先,思考下以下问题:

  • 什么是进程?
  • 什么是程序?
  • 进程:是一个动态的概念 程序开启才会启动
  • 程序:是存放在磁盘文件中的可执行文件

进程ID

  • 每个linux进程都一定有一个唯一的数字标识符,称为进程ID(进程ID总是非负整数)

Linux下的进程结构

  • Linux系统是一个多进程的系统,进程之间具有并行性、互不干扰的特点
  • Linux中进程包含PCB(进程控制块)、程序以及程序所操纵的数据结构集
  • 可分为“代码段”、“数据段”和“堆栈段”

【Linux学习】 进程管理 fork系统调用 创建子进程 阻塞父进程_第1张图片

进程状态

  • 运行状态R(TASK_RUNNING)
  • 可中断睡眠状态S(TASK_INTERRUPTIBLE)
  • 不可中断睡眠状态D(TASK_UNINTERRUPTIBLE)
  • 暂停状态T(TASK_STOPPED或TASK_TRACED)
  • 僵死状态Z(TASK_ZOMBIE)
  • 退出状态X  (TASK_DEAD)

进程状态转换图

【Linux学习】 进程管理 fork系统调用 创建子进程 阻塞父进程_第2张图片

init进程

  • 进程ID为1通常是init进程,在自举过程结束时由内核调用
  • init进程绝不会终止
  • 它是一个普通的用户进程(与交换进程不同,它不是内核中的系统进程),但是它以超级用户特权运行

二、fork系统调用

  • 一个进程,包括代码、数据和分配给进程的资源
  • fork()函数,通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事
  • 一个进程调用 fork()函数后,系统先给新的进程分配资源,例如,存储数据和代码的空间,然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同,相当于克隆了一个自己

fork相关头文件

#include 
#include 

fork函数原型

pid_t fork(void);

返回值:

子进程中为0,父进程中为子进程ID

出错为-1

Linux手册查看

Linux下进入终端输入以下命令行,如下图所示:

【Linux学习】 进程管理 fork系统调用 创建子进程 阻塞父进程_第3张图片

fork创建代码示例

利用 Visual Studio 2019 进行跨平台编程开发,代码如下:

#include 
#include 
#include 

using namespace std;

int main()
{
	pid_t pid;
	pid_t pidtest;
	int number = 1;

	pid = fork(); //一次调用 两次返回

	if (pid == 0)
	{
		cout << "子进程 fork返回值 = " << pid << endl;
		cout << "子进程 pid = " << getpid() << endl;

		for (int i = 0; i < 10; i++)
		{
			number++;
			cout << "子进程 number = " << number << endl;
		}
	}
	else if (pid > 0)
	{
		cout << "父进程 fork返回值 = " << pid << endl;
		cout << "父进程 pid = " << getpid() << endl;

		for (int i = 0; i < 10; i++)
		{
			number++;
			cout << "父进程 number = " << number << endl;
		}
	}

	return 0;
}

跨平台连接 Linux 后运行

运行效果

【Linux学习】 进程管理 fork系统调用 创建子进程 阻塞父进程_第4张图片

注意点

  • fork系统调用之后,父子进程将交替执行,如果父进程先退出,子进程还没退出那么子进程的父进程将变为init进程(注:任何一个进程都必须有父进程)
  • 如果子进程退出,父进程还没退出,那么子进程必须等到父进程捕获到了子进程的退出状态才真正结束,否则这个时候子进程就会成为僵尸进程

以上就是本文的全部内容啦!如果对您有帮助,麻烦点赞啦!收藏啦!欢迎各位评论区留言!!!

【Linux学习】 进程管理 fork系统调用 创建子进程 阻塞父进程_第5张图片

你可能感兴趣的:(Linux学习,学习,linux,c++)