进程

进程是操作系统分配资源的基本单位!操作系统是以进程为单位来分配系统资源的,比如内存空间、CPU使用权等。 线程是操作系统调度资源的最小单位! 进程包含线程!
进程具有四个基本特征,分别是动态性、并发性、独立性、异步性,具体的区别如下所示:

(1)动态性:进程是程序在处理器上的一次执行过程,因而是动态的。比如进程会在程序运行时被创建出来,当无法获取足够的系统资源时进程会暂停,当得到资源后会继续执行。

(2)并发性:多个进程同时存在于内存中,目的是与其他程序并发执行,提高资源的利用率。

(3)独立性:进程是一个能独立运行的基本单位,也是系统进行资源分配和调度的独立单位。

(4)异步性:指的是进程以各自独立的、不可预知的速度向前推进。一个进程的执行过程可能是无法被预测的,因为会受到各方面因素的影响,比如当系统资源不够时或者出现其他进程抢占资源时,都会影响进程的执行进度。

操作系统中可能会有n个进程同时执行,请问操作系统如何掌握这些进程的执行情况?
一般进程在创建之后,操作系统都会为进程分配一块内存来记录进程的各项参数信息,所以这块内存被称为进程控制块(Processing Control Block,缩写为PCB)。每个进程都有PCB,用于标识进程的存在以及记录进程的信息。
每个进程都有一个有系统分配的唯一的PID进程标识符(process identifier),用于区分系统中的其他进程,这个PID也是Linux内核提供给用户访问进程的一个接口,用户可以通过PID控制进程。

windows系统下可以通过任务管理器查看进程的PID,那Linux系统如何查看进程PID?
Linux系统中提供了关于获取进程状态的shell命令:ps ,该命令的使用方法详见man手册,一般使用 ps -ef 或者 ps -aux来查看Linux系统中所有用户相关的进程的所有信息。
在Linux系统的终端中输入shell指令: ps -aux,就可以看到当前系统中运行的进程状态。
image

进程的控制:
1)进程的创建:
在Linux系统中运行的所有进程也可以构成一个进程树,并且该进程树也有一个祖先,用户可以通过Linux系统提供的shell命令:pstree 来打印进程关系。
image
可以发现,Linux系统中的所有进程都和一个进程有关系,那就是systemd进程,该进程是Linux系统运行的第一个进程,英文全称是system daemon,中文翻译为系统守护进程,系统中其他进程都是该进程的子进程。
systemd其实是一个 Linux 系统基础组件的集合,它提供了一个系统和服务管理器,然后运行为 PID 1的进程,负责在系统启动或运行时激活系统资源,并且管理服务器进程和其它进程。
Linux系统中只有进程才可以在系统运行,所以一个程序想要运行,就必须为该程序创建进程。linux内核提供了一个名字叫做fork()的系统调用接口,该接口可以在进程中创建一个子进程。
image
可以看到fork函数的返回值对于父进程和子进程而言是不同的,fork函数在父进程中返回的是创建成功的子进程的PID,fork函数在子进程中的返回值是0,当然,如果子进程失败则返回-1。(一般用pid_t这个类型接收)
编写程序,要求在程序中创建一个子进程,让父进程和子进程分别打印不同的内容:

点击查看代码

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char const *argv[])
{
	int fd = 3; // 父进程的数据段

	//创建子进程,调用fork函数的时候就已经创建子进程
	pid_t child_pid = fork(); 

	//通过fork函数的返回值分析父进程 or 子进程
	if (child_pid > 0)
	{
		//说明是父进程的进程空间
		printf("my is parent,my pid = %d,my child pid = %d\n",getpid(),child_pid);
		while(1);

	}
	else if( child_pid == 0)
	{
		//说明是子进程的进程空间
		printf("my is child,my pid = %d,my parent pid = %d\n",getpid(),getppid());
	}
	else
	{
		printf("child process fork error\n");
		return -1;
	}

	

	return 0;

}

2)进程的撤销
一个进程在完成自身任务之后应该及时撤销,这样就可以及时的释放进程的资源,此时可以分为两种情况:一种是撤销指定进程,另一种是撤销指定进程以及该进程的所有子孙进程。不管是哪种情况,都应该及时回收进程占用的资源。
Linux系统中提供了一个名称叫做wait()的系统调用接口,该接口用于让父进程等待子进程的状态改变并获取已经改变状态的子进程的信息。
image
僵尸态指的是进程终止但是并未释放相关资源的一种状态,此时由系统内核对处于僵尸态的进程进行维护,处于僵尸态的进程会占用创建进程的资源和数量,如果僵尸态进程数量太多,则会导致系统无法创建新进程。
所以父进程应该及时的对终止的子进程进行等待,这样就可以回收子进程占用的资源,当然,如果父进程终止,则处于僵尸态的子进程会由系统内核完成资源的回收。
wait函数的参数是一个指针,用于记录子进程的退出状态,如果该参数为NULL,则表示当前进程放弃子进程的退出状态。对于该指针中记录的值,用户可以通过系统提供的宏定义来分析子进程的退出状态。
image
3)进程的执行
image
关于他的使用:
父进程用system,让子进程运行其他东西

点击查看代码
 #include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char const *argv[])
{
	int fd = 3; // 父进程的数据段

	//创建子进程,调用fork函数的时候就已经创建子进程
	pid_t child_pid = fork(); 

	//通过fork函数的返回值分析父进程 or 子进程
	if (child_pid > 0)
	{
		//说明是父进程的进程空间
		printf("my is parent,my pid = %d,my child pid = %d\n",getpid(),child_pid);
		while(1);

	}
	else if( child_pid == 0)
	{
		//说明是子进程的进程空间
		printf("my is child,my pid = %d,my parent pid = %d\n",getpid(),getppid());
        system("./deom");
	}
	else
	{
		printf("child process fork error\n");
		return -1;
	}

	

	return 0;

}
点击查看代码
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main(int argc,char const *argv[]){
    //1.打开文件
    int fd_t = open("./deom.txt",O_RDWR|O_CREAT);
    if(-1 == fd_t){
        fprintf(stderr,"open deom.text error,the errorno = %d,%s\n",errno,strerror(errno));
        return -1;
    }
    //2.写入
    write(fd_t,"hello world",11);
    //3.读
    char recv_buf[20] = {0};
    lseek(fd_t,0,SEEK_SET);
    read(fd_t,recv_buf,11);
    printf("the str is %s",recv_buf);
    //4.close
    close(fd_t);
}
posted @ 2025-08-07 18:39  Lè_Sage  阅读(94)  评论(0)    收藏  举报