Linux常用进程控制命令
这里仅简单介绍命令及基本功能,详细信息请自行利用man命令进行查询。
命令名 | 功能 |
---|
ps | 查看系统中的进程 -A 列出所有进程 -aux 显示所有进程较详细的信息(包括没有控制终端的进程),所含信息为: USER PID %CPU %MEM VSZ(占用的虚拟内存大小) RSS(占用的实际内存大小) TTY(终端设备编号) STAT(进程状态) START TIME(运行时间) COMMAND(执行的命令) | top | 动态显示系统中的进程 | nice | 按照指定的优先级运行命令(优先级越高的进程获取的cpu资源就越多) | renice | 改变正在运行进程的优先级 | kill | 向进程发送信号,一般用于终止进程,如:kill -9 pid(彻底杀死进程) |
进程相关函数
getpid、getppid
函数名 | getpid |
---|
头文件 | #include<unistd.h> | 函数原型 | pid_t getpid(void) | 返回值 | 当前进程的进程号 |
函数名 | getppid |
---|
头文件 | #include<unistd.h> | 函数原型 | pid_t getppid(void) | 返回值 | 当前进程的父进程号 |
sleep
函数名 | sleep |
---|
头文件 | #include<unistd.h> | 功能 | 让进程休眠一段时间 | 函数原型 | unsigned int sleep(unsigned int seconds) | 传入值说明 | 单位为秒 | 返回值 | 成功返回0,中途被唤醒则返回剩余的秒数 |
fork
函数名 | fork |
---|
头文件 | #include<unistd.h> | 功能 | 建立一个新的进程 | 函数原型 | pid_t fork(void) | 返回值 | 子进程返回0,父进程返回子进程的pid | 备注 | 新的进程和父进程共享代码片段和变量,但是变量只有在被使用的时候才会进行复制,并且父子进程的变量不会同步。在子进程中,只有产生子进程的那个fork()会返回一个0,但是只有产生子进程的fork之后的fork才会产生新的进程。 |
下面这段代码一共产生了四个进程。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
int res1 = fork();
int res2 = fork();
printf("当前进程的pid为:%d,父进程的pid为:%d,res1=%d,res2=%d\n", getpid(), getppid(), res1, res2);
sleep(1);
return 0;
}
下面是运行结果,可以看到第一个fork产生的子进程中第二个fork是正常运行的,但是第二个fork产生的子进程中两个fork都不会产生新的进程。
exec函数族
函数名 | exec函数族 |
---|
头文件 | #include<unistd.h> | 功能 | 用一个新的进程替代当前进程,pid不变 | 函数原型 | int execl(const char *path, const char *arg, …) int execv(const char *path, char const *argv[], …) int execle(const char *path, const char *arg, …, char *const envp[]) int execve(const char *path, char const *argv[], char *const envp[]) int execlp(const char *file, const char *arg, …) int execvp(const char *file,char const *argv[]) | 返回值 | 失败返回-1,如果成功了是不会接收到返回值的(因为当前进程被新的进程替代了) | 备注 | 函数最后的字符l、v、e、p分别表示: l:列表传递方式 v:字符指针数组传递方式 e:可指定环境变量 p:路径自动搜索功能(可以不用输入完整的路径名) |
#include <stdio.h>
#include <unistd.h>
int main()
{
execl("/bin/ls", "ls", "-l", 0);
perror("调用ls失败\n");
return 0;
}
运行截图
exit
函数名 | exit |
---|
头文件 | #include<unistd.h> | 功能 | 正常终止进程 | 函数原型 | void exit(int status) | 备注 | 正常终止进程,并将参数status返回给父进程,终止前会将缓冲区内的数据写回未关闭的文件中。 |
函数名 | _exit |
---|
头文件 | #include<unistd.h> | 功能 | 正常终止进程 | 函数原型 | void _exit(int status) | 备注 | 立刻终止进程,并将参数status返回给父进程,但不会处理IO缓冲区,因此不建议使用 |
wait、waitpid
函数名 | wait |
---|
头文件 | #include<sys/types.h> #include<sys/wait.h> | 功能 | 阻塞当前进程直到子进程中断或结束 | 函数原型 | pid_t wait(int *status) | 传入值说明 | 如果不是NULL,会将子进程退出时的状态存入status,注意并不是子进程的返回值 | 返回值 | 成功返回子进程的pid,有错误返回-1 |
函数名 | waitpid |
---|
头文件 | #include<sys/types.h> #include<sys/wait.h> | 功能 | 阻塞当前进程直到子进程中断或结束 | 函数原型 | pid_t waitpid(pid_t pid, int *status, int options) | 传入值说明 | pid:子进程号 status:子进程结束状态 options可以为0或以下组合: WNOHANG:如果没有任何已终止的子进程则马上返回,不予等待 WUNTRACED:如果子进程进入暂停执行则马上返回,但对终止状态不予理会 | 返回值 | 成功返回子进程的pid,有错误返回-1 |
setsid
函数名 | setsid |
---|
头文件 | #include<sys/types.h> #include<unistd.h> | 功能 | 设置新的组进程号(使当前进程脱离终端和父进程的控制,一般用于守护进程) | 函数原型 | pid_t setsid(void) | 返回值 | 成功返回子组进程号GID,有错误返回-1 | 备注 | 使用setsid产生守护进程的步骤一般为父进程先fork一个子进程,然后父进程结束进程,子进程调用setsid成为守护进程,修改工作目录(防止因为当前目录被删除导致守护进程退出),修改权限掩码,此时关闭终端也不会结束子进程。 |
下面的程序在运行后会在一分钟内每隔一秒向所有终端广播hello,即使退出了终端也会继续运行。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
int main()
{
pid_t res = fork();
if (res > 0)
exit(0);
else if (res == 0)
{
setsid();
chdir("/tmp");
umask(0);
int cnt = 60;
while (cnt--)
{
system("wall hello");
sleep(1);
}
}
return 0;
}
|