linux应用软件编程之多任务(进程)详解

 更新时间:2025年08月15日 09:31:01   作者:Twinkle175  
文章介绍了进程与多任务的概念,涵盖进程定义、状态(运行、就绪、等待、僵尸等)、调度算法及资源回收机制,并列举了ps、top、kill等系统命令和fork、exit等编程方法,说明如何创建、管理及终止进程

一、多任务概述

1.定义:

让系统具备同时处理多个任务的能力

2.实现过程

  • 多进程
  • 多线程
  • 进程间通信

二、进程概述

1.定义

一个正在运行的程序称为一个进程,其运行过程中需要消耗内存和CPU。

2.程序和进程的区别

                       程序                                                                                        进程

静态的数据集合,存储在硬盘空间                    是一个程序动态执行的过程,需要消耗内存和CPU

程序运行起来可以产生进程                               进程具备动态生命周期,从产生到调度再到消亡

一个程序可以产生多个进程                               一个进程中也可执行多个程序

3.进程的产生

进程产生时,操作系统都会为其分配0-4G的虚拟内存空间。操作系统内存区如下图所示:

(1)内核: 1 文件管理;2. 进程管;3. 内存管理。

(2)栈区:1.保存局部变量;2.函数的形参和返回值;3.保存函数的调用关系(保护现场和恢复现场)。

(3)堆区:1. 由开发人员手动分配;2. 使用完要手动释放。

(4)数据区:

  • data段:1. 已初始化的全局变量 ;2. 已初始化的静态变量。
  • bss段:1.未初始化的全局变量 ; 2. 未初始化的静态变量(static)-->bss段初始时按位清0。
  • 字符串常量区:保存字符串常量   "hello world"

(5)文本区:1. 存放指令代码   ;2. 存放常量。

4.进程的调度

  • CPU:

由于CPU数据处理速度快,因此是“宏观并行,微观串行”。

  • cpu调度算法

1、时间片轮询算法

2、先来先服务,后来后服务(任务队列)

3、短作业优先调度

4、高优先级先执行,低优先级后执行

5.进程的状态

  • 操作系统的三态图:

  • Linux操作系统的进程状态:

  • 各进程状态:

1.运行态(用户运行态、内核运行态)     R

正在执行,且被CPU任务调度所执行的进程    

2.就绪态    R

正在执行,没有CPU任务调度执行的进程(只缺少cpu)

3.可唤醒等待态    S

也称为睡眠态,阻塞等待资源的进程

4.不可唤醒等待态 D

不想被CPU任务调度所打断的进程任务可以设置为不可唤醒等待态       

5.暂停态    T

被暂停执行的进程        

6.僵尸态    Z

进程执行结束,空间没有被回收        

7.结束态    X

进程执行结束,空间被回收

6.进程的消亡

  • 进程执行结束(进程退出)
  •  回收进程资源空间

三、进程相关的命令

  • 父进程:产生子进程的进程称为父进程
  • 子进程:父进程产生出来的新进程即为该父进程的子进程

1. ps  -aux

查看进程相关参数:PID、状态、CPU占有率、内存占有率

  • USER:创建者
  • PID:进程的ID号
  • %CPU:CPU占有率
  • %MEM:内存占有率
  • TTY:当前进程所关联的终端
  • STAT:当前进程的状态值(带“+”号表示前台进程,不带“+”号表示后台进程)
  • START TIME:进程创建的时间
  • COMMAND:进程的名称(init进程是操作系统启动的第一个进程)
ps -aux | grep ./a.out
  • |:管道 :前面命令的输出作为后面命令的输入
  • grep:字符串查找:在输入中查找和后面字符串相关的数据        

 

2. top

动态查看进程的相关参数:CPU占有率、内存占有率

——按照CPU、内存占有率的高低进行排列的

  • PR、NI:表示进程的优先级,值越小,优先级越高
  • TIME+:进程运行的时间

3. ps -ef查看该进程的ID和父进程ID

4. pstree查看进程的产生关系

pstree -p

查看进程的产生关系(有PID号)

pstree -sp  进程PID号

查看某个指定的进程的产生关系

5.kill

kill -信号的编号/信号的名称  PID

向进程发送信号,让进程的状态发生变化

由第一张图片中可以看出20429进程一开始是在R+运行状态,执行kill相关命令,其进程被杀死。

结束一个进程的三种表示形式:

kill -9 PID
kill -SIGKILL PID
killall -9  进程名称
kill -l

查看系统支持的信号

  • 9——SIGKILL——杀死信号
  • 19——SIGSTOP——暂停态信号
  • 18——SIGCONT——唤醒信号

+前台进程后台进程

6. jobs查看当前终端的后台进程

7.fg

[ fg 后台进程编号]

让后台进程切换成前台进程

四、进程相关的编程

1.实现进程的步骤

进程创建 :   fork()

  • getpid():获取当前进程自己的PID号
  • getppid():获取当前进程父进程的PID号

进程调度:操作系统完成

进程消亡:

  • 1.进程退出:return、exit()相关函数
  • 2.回收资源空间:wait()、waitpid()

2.进程创建函数

pid_t fork(void);

功能:通过拷贝父进程产生一个新的子进程

  • 子进程完全拷贝父进程0-3G的虚拟内存空间
  • 子进程拷贝父进程PCB(进程控制块)块中的部分内容:PID不拷贝

返回值:

  • >0:父进程 ,是子进程的PID号
  • ==0:子进程
  • -1 :出错

3.示例程序

使用fork函数创建新进程,

  • 父进程打印自己的PID和自己子进程的pid
  • 子进程中打印自己的PID和父进程的PID
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc , const char *argv[])
{
    
    pid_t pid = fork();

    if(pid > 0)
    {   
       
        while(1)
        {   
            printf("I am father pid = %d sonpid = %d \n",getpid(),pid);
            sleep(1);
        }
    }
    else if(0 == pid)
    {   
        
        while(1)
        {

            printf("I am son pid = %d ppid = %d \n",getpid(),getppid());
            sleep(1);
        }
    }
    else
    {
        perror("fork error");
    }

    return 0;
}

注意:

1. 子进程完完整整拷贝父进程0-3G虚拟内存空间。

2. 父子进程栈区、数据区、文本区、堆区完全独立,数据不共享

3. 要想共享数据,需要使用进程间通信方式实现

例如以下程序:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc , const char *argv[])
{
    
    pid_t pid = fork();
    int num = 0;
    if(pid > 0)
    {   
       num = 100;
        while(1)
        {   
            printf("I am father pid = %d sonpid = %d  num = %d\n",getpid(),pid,num);
            sleep(1);
        }
    }
    else if(0 == pid)
    {   
        num = 1000;
        while(1)
        {

            printf("I am son pid = %d ppid = %d num = %d\n",getpid(),getppid(),num);
            sleep(1);
        }
    }
    else
    {
        perror("fork error");
    }

    return 0;
}

运行结果如下:

3.进程退出函数

(1)main中return

#include <stdio.h>
#include <stdlib.h>
int fun()
{
	return 0;
}
int main(int argc, const char *argv[])
{

	int i = 15;
	while (i--)
	{
		printf("PID = %d\n", getpid());
		sleep(1);
	}

	return 0;
}

 (2) exit ()、_exit() :结束一个进程

  • exit (0) : 正常退出
  • exit (非0) :由于进程产生了某种问题,需要主动退出进程
#include <stdio.h>
#include <stdlib.h>
int fun()
{
	exit(0);
	return 0;
}
int main(int argc, const char *argv[])
{

	fun();
	
	printf("hello world\n");
	return 0;
}

4.回收资源空间:

wait()、waitpid()

僵尸进程:进程退出后,但其资源空间未被父进程回收

如何避免僵尸进程产生:

1.  子进程退出后,父进程及时为其回收资源空间

2.  让该进程成为一个孤儿进程,结束时被操作系统中的系统进程回收

孤儿进程:父进程先消亡,其对应的子进程成为一个孤儿进程,会被系统进程所收养

(守护类的进程)

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, const char *argv[])
{
	pid_t pid = fork();
	if (pid > 0)
	{
	
		while (1)
		{
		
			printf("I am father : pid = %d, sonpid = %d\n", getpid(), pid);
			sleep(1);
		}
	}
	else if (0 == pid)
	{
		int i = 15;
		while (i--)
		{
			printf("I am son : pid = %d, ppid = %d\n", getpid(), getppid());
			sleep(1);
		}
	}
	else
	{
		perror("fork error");
	}
	return 0;
}
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, const char *argv[])
{
	pid_t pid = fork();
	if (pid > 0)
	{
		int i = 10;	
		while (i--)
		{
		
			printf("I am father : pid = %d, sonpid = %d\n", getpid(), pid);
			sleep(1);
		}
	}
	else if (0 == pid)
	{
		int i = 20;
		while (i--)
		{
			printf("I am son : pid = %d, ppid = %d\n", getpid(), getppid());
			sleep(1);
		}
	}
	else
	{
		perror("fork error");
	}
	return 0;
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Linux设置虚拟内存的教学与实战教程

    Linux设置虚拟内存的教学与实战教程

    这篇文章主要给大家介绍了关于Linux设置虚拟内存教学与实战的相关资料,文中通过示例代码以及图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03
  • Centos7安装ElasticSearch 6.4.1入门教程详解

    Centos7安装ElasticSearch 6.4.1入门教程详解

    这篇文章主要介绍了Centos 7安装ElasticSearch 6.4.1入门教程详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-05-05
  • Linux 僵尸进程产生原因及解决方法

    Linux 僵尸进程产生原因及解决方法

    这篇文章主要介绍了Linux 僵尸进程产生原因及解决方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02
  • htaccess 将所有请求重定向到某个URL地址的规则

    htaccess 将所有请求重定向到某个URL地址的规则

    htaccess 将所有请求重定向到某个URL地址的规则,需要的朋友可以参考下。
    2011-04-04
  • win7中VMware安装CentOs7搭建Linux环境教程

    win7中VMware安装CentOs7搭建Linux环境教程

    这篇文章主要为大家详细介绍了win7中VMware虚拟机安装CentOs7搭建Linux环境教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • 如何解决linux重启ip地址改变的问题

    如何解决linux重启ip地址改变的问题

    这篇文章主要介绍了如何解决linux重启ip地址改变的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • linux 安装配置lamp v2

    linux 安装配置lamp v2

    距离第一个版本已经有一年了。修正了几个错误的地方,还有取消了某些lib的安装,因为centos有,所以相关的lib安装我都没有去查找错误。
    2009-02-02
  • Linux IO多路复用之epoll网络编程

    Linux IO多路复用之epoll网络编程

    今天小编就为大家分享一篇关于Linux IO多路复用之epoll网络编程,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • Kali Linux静态IP的设置指南

    Kali Linux静态IP的设置指南

    在 Kali Linux 中设置静态 IP 地址是一个常见的需求,尤其是在进行渗透测试或者需要长期稳定连接的情况下,本文将指导你如何在 Kali Linux 中配置静态 IP 地址,感兴趣的小伙伴跟着小编一起来看看吧
    2024-12-12
  • 解决centos桌面在虚拟机中界面显示太小问题

    解决centos桌面在虚拟机中界面显示太小问题

    这篇文章主要介绍了解决centos桌面在虚拟机中界面显示太小问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08

最新评论