什么是进程?

要弄清楚什么是进程,我们要先理解什么是程序,什么是代码。代码顾名思义,大家都知道,我们平时所敲出来的那一堆文本就是代码,那程序呢,程序是**代码经过编译/链接后所形成的可执行文件,程序所在的位置也是至关重要,程序存在于磁盘上,是一个静态文件。**接下来,我们就可以知道进程是什么了:

**进程是程序被加载到内存并开始运行后的"实例"。**我们只需要知道,程序本来在磁盘上,如果我们把他加载到内存上运行起来,那么这就是个进程。

进程是操作系统进行资源分配和调度的基本单位。

1 进程处理相关函数介绍

首先明确一些概念:

(1)pid:pid全称是process id,指的是进程的id;

(2)子进程与父进程:由父进程创建的进程叫做子进程,一般情况下子进程继承父进程的"运行环境",但拥有独立的执行生命周期;

1.1 获取进程id

**pid_t getpid(void):**获取当前进程id;
**pid_t getppid(void):**获取父进程id;

每个进程都有一个独立的pid。

1.2 创建进程

最常见的创建进程的方式fork

pid_t fork(void):复制当前进程,创建一个子进程;

返回值(重点):

父进程:返回子进程pid;

子进程:返回0;

失败返回-1;

返回值部分看代码应该更清晰一点。

接下来我们讲execve()函数,很多人会把execve跟fork弄混。

**fork:**创建一个新的进程(子进程);

**execve:**保持原进程不变,只是运行一个新的程序,但还是在原进程跑的这个程序,也就是execve之后pid不变;

int execve(const char *pathname, char *const argv[], char *const envp[]);

参数:

**const char* pathname:**要运行的新的程序的绝对路径(可执行文件)(execve 不会搜索 PATH);

char* const argv[]: 给新程序main函数的参数,一个"以 NULL 结尾的字符串指针数组";

char* const envp[]: 环境变量数组,一个"以 NULL 结尾的字符串指针数组";

**返回值:**成功则没有返回值,因为已经去运行另一个程序了,存在返回值也没有意义,失败返回-1;

1.3进程退出

进程退出的方法有:exit()/_exit()/return

void _exit(int status):_exit是系统调用,用于立即终止一个进程,定义在uinstd.h中。这个调用确保进程立即退出,不执行任何清理操作。一般用于子进程终止,防止子进程影响父进程。

void exit(int status):exit()由c标准库函数提供,定义在stdlib.h中,作用是终止当前进程,但在此之前会执行三种清理操作。一般在父进程使用exit();

系统调用不进行清理,库函数exit进行清理操作;

清理操作具体指:**用户态清理,**刷新 stdio 缓冲、调用atexit注册函数等,然后再进入内核结束进程。

1.4等待与回收进程

进程运行结束是需要回收的,子进程是需要其父进程帮忙回收的,子进程退出后,如果父进程不回收,会留下 僵尸进程(Z)。所以父进程一般会等待子进程运行结束后,帮忙回收,然后再结束自己的进程。

故而会存在一些父进程等待子进程的函数如wait/waitpid等

pid_t wait(int *wstatus):等待任意一个子进程结束并回收;成功返回回收的子进程pid,失败返回-1;

**pid_t waitpid(pid_t pid, int *wstatus, int options):**等待指定的进程;

参数:

pid_t pid:等待的子进程id;为-1时则等待任意子进程;

int options:0:阻塞等待,WHOHANG:非阻塞等待;

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐