0.与进程相关的重要命令
1.ps命令
①.ps -aux可查看所有进程的相关信息
②.ps -aux|grep 可筛选想要查询的相关进程
2.top命令
top命令主要是用来查看系统当前的进程占用的CPU资源的情况,以便于优化。
linux@ubuntu:~$ top
一.C函数(进程的创建与结束)
1.进程创建 - fork
创建新的进程,失败时返回-1,成功时(返回两个值)父进程返回子进程的进程号,子进程返回0。并且子进程会继承父进程的内容(数据、代码、文件描述符等)。
但是,父进程和子进程的地址空间是独立的(子进程相当于存了一个父进程资源的备份)。从继承的那一刻起,父子进程内部的变量等内容互不影响。即继承过后,父进程/子进程改变某一变量的值,子进程/父进程内的那个变量值是不受影响的。
pid_t fork(void);
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t pid;
pid = fork();
/* 若fork创建子进程成功,子进程从这里开始运行 */
switch(pid)
{
case -1:
printf("子进程创建失败\n");
break;
/* pid==0时,里面执行的是子进程的代码 */
case 0:
printf("这是子进程,pid = %d\n",getpid());
break;
default:
printf("这是父进程,pid = %d\n",getpid());
break;
}
return 0;
}
2.结束当前的进程 - exit() _exit()
结束当前的进程,并将status返回。status表示了结束前的进程的状态。
void exit(int status);
void __exit(int status);
3.exec函数族
作用:1.进程调用exec函数族,让当前的进程去执行某个程序
2.进程当前内容被指定的程序替换
3.实现让父子进程执行不同的程序
(1).父进程创建子进程
(2).子进程调用exec函数族
(3).父进程不受影响
①.execl和execlp
成功时执行指定的程序;失败时返回EOF
execl()
path:执行的程序的名称,包含路径
arg...:传递给执行的程序的参数列表()
execlp()
file:指定执行的程序的名称,不需要路径,在环境变量中自动找
arg...:
int execl(const char *path,const char *arg,...); //arg最后要以NULL结尾
int execlp(const char *file,const char *arg,...); //arg最后要以NULL结尾
②.execv和execvp
成功时执行指定的程序;失败时返回EOF
file :与path、file与execl、execlp一致。
*argv[]:指针数组的地址,将要传入的参数先放入指针数组,再将此数组传入execv和execvp
int execv(const char *path,char *const argv[]);
int execvp(const char *file,char *const argv[]);
4.system函数
使用system(const char *command)后,会自动创建一个子进程去执行command中的程序。
成功时返回命令command的返回值;失败时返回EOF。
int system(const char *command);
二.C函数(进程资源回收)
僵尸进程:当子进程比父进程先结束时,若父进程没有及时回收子进程的资源,那么该子进程会成为僵尸进程
为避免这种情况,Linux下引入了进程回收函数。
1.wait函数
功能:回收子进程的资源;
成功时返回(回收的子进程的进程号),失败时返回(EOF);
若子进程没有结束,父进程会阻塞等待子进程结束再回收;
若有多个子进程,哪个先结束就先回收;
参数:status,指定保存子进程返回值和结束方式的地址。
当status传入NULL时,直接释放子进程的资源,不关心返回值。
pid_t wait(int *status);
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
pid_t pid;
pid = fork();
switch(pid)
{
case -1:
printf("子进程创建失败\n");
break;
case 0:
printf("这是子进程,pid = %d\n",getpid());
break;
default:
printf("这是父进程,pid = %d\n",getpid());
pid = wait(NULL);
printf("结束子进程:%d\n",pid);
break;
}
return 0;
}
2.进程返回值和结束方式
父进程调用wait(&status)回收子进程,我们可以通过status判断子进程结束的状态
①.WIFEXITED(status) : 判断子进程是否正常结束(被信号终止则为不正常结束)。
②.WEXITSTATUS(status) :判断子进程的返回值
③.WIFSIGNALED(status) :判断子进程是否被信号结束
④.WTERMSIG(status) :获取结束子进程的信号类型
3.waitpid函数
功能:
成功时返回(回收的子进程的进程号或0),失败时返回(EOF)
(若返回0,表示当前子进程还没有结束)
参数:
pid : 指定回收的进程
status :与wait函数中的status功能一样
option : 指定回收的方式
0:父进程阻塞等待子进程结束后再回收
WNOHANG:父进程不阻塞
pid_t waitpid(pid_t pid,int *status,int option);
三.守护进程
特点:
守护进程通常在系统启动时运行,系统关闭时结束。很多服务程序以守护进程形式运行;
始终在后台运行;
与终端无关联;
周期性的去执行某种任务任务或等待处理特定事件。