怎样在百度做网站表白,聚焦伟业网站怎么做推广,营销最好的网站建设公司,重庆建设工程信息网官网查询入口文章目录 1.进程的三种基本状态2.Linux中进程状态查看2.1.进程检测脚本2.2.各种状态查看 3.孤儿进程4.前台、后台、守护进程 1.进程的三种基本状态
进程的在系统当中是走走停停的#xff0c;「运行 - 暂停 - 运行」的活动规律#xff1b;进程在活动期间的三种状态#xff1… 文章目录 1.进程的三种基本状态2.Linux中进程状态查看2.1.进程检测脚本2.2.各种状态查看 3.孤儿进程4.前台、后台、守护进程 1.进程的三种基本状态
进程的在系统当中是走走停停的「运行 - 暂停 - 运行」的活动规律进程在活动期间的三种状态运行状态、就绪状态、阻塞状态。 运行状态Running该时刻进程占用 CPU就绪状态Ready可运行由于其他进程处于运行状态而暂时停止运行阻塞状态Blocked该进程正在等待某一事件发生或等待非CPU资源如等待输入/输出IO操作的完成而暂时停止运行这时即使给它CPU控制权它也无法运行
PCB是描述进程信息的结构体它是通过链表的方式组织的。如果处于就绪状态的进程链在一起的是运行队列而处于阻塞状态的进程链在一起的是阻塞队列在Linux中就绪和运行态都是R状态。来看看kernel源代码对进程状态的定义
/*
* The task state array is a strange bitmap of
* reasons to sleep. Thus running is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] {R (running), /* 0 */S (sleeping), /* 1 */D (disk sleep), /* 2 */T (stopped), /* 4 */t (tracing stop), /* 8 */X (dead), /* 16 */Z (zombie), /* 32 */
};2.Linux中进程状态查看
2.1.进程检测脚本
while :; do ps axj | head -1 ps axj | grep mytest;sleep 1;echo ------------------;done更加干净
while :; do ps axj | head -1 ps axj | grep mytest | grep -v grep;sleep 1;echo ------------------;done2.2.各种状态查看
R运行状态running: 并不意味着进程一定在运行中它表明进程要么是在运行中要么在运行队里。测试代码
#include stdio.h
#include unistd.hint main()
{while(true){printf(hello world\n);sleep(1);}return 0;
}测试结果R后面的进程代表是一个前台进程 S睡眠状态sleeping): 进程在等待事件完成这里的睡眠有时候也叫做可中断睡眠interruptible sleep
#includestdio.h
int main()
{ int a 0; printf(请输入一个整数); scanf(%d,a); return 0;
} 测试结果 D磁盘休眠状态Disk sleep有时候也叫不可中断睡眠状态uninterruptible sleep在这个状态的进程通常会等待IO的结束不能被叫醒
可以使用dd命令来测试dd命令在处理数据时非常强大但同时也具有一定的风险性。如果使用不当可能会导致数据丢失或损坏建议是不用测试这个状态
T停止状态stopped 可以通过发送 SIGSTOP kill -19 pid信号给进程来停止T进程。这个被暂停的进程可以通过发送 SIGCONTkill -18 pid 信号让进程继续运行。**典型应用调试断点能停下来是因为进程的T状态**测试代码
使用命令kill -19 pid将进程暂停
使用命令kill -18 pid将进程运行
#include stdio.h
#include unistd.hint main()
{while(true){printf(hello world\n);sleep(1);}return 0;
}测试结果 Z状态僵尸死状态 当子进程退出但是父进程没调用wait或waitpid去获取子进程的状态信息没有检测到子进程返回状态的代码时子进程就会处于一个被检测的状态就是僵尸状态。测试代码
#includestdio.h
#includeunistd.hint main()
{ pid_t ret fork();if(ret 0){perror(fork faile\n);return 1;}else if(ret 0){int cnt 5;while(cnt){printf(I am child pid %d\n,getpid());cnt--;sleep(1);}}else { while(1) { printf(I am father pid %d\n,getpid()); sleep(1);} } return 0;
}测试结果
在这里插入图片描述
僵尸进程的危害子进程被创建出来是为了完成父进程交给它的任务父进程需要读取子进程的返回状态但是父进程先退出那么子进程就要一直维护Z状态系统要一直维护子进程的PCB那么就会造成内存泄漏。
父进程通过调用wait 或 waitpid进程等待的方式解决僵尸进程问题。
3.孤儿进程
孤儿进程父进程结束了而它的一个或多个子进程还在运行那么这些子进程就成为孤儿进程(father died)。子进程的资源由init进程(进程号PID 1)回收。
测试代码
#include stdio.h
#include unistd.h
#include stdlib.h
int main()
{pid_t id fork();if (id 0){perror(fork);return 1;}else if (id 0){printf(I am child, pid : %d\n, getpid());sleep(10);}else{ printf(I am parent, pid: %d\n, getpid());sleep(3);exit(0);}return 0;
}测试结果 4.前台、后台、守护进程 前台进程通常是用户正在交互的进程本质是谁占有键盘资源谁就是前台进程 #include stdio.h
#include unistd.h
#include stdlib.hint main()
{while(true){printf(hello world\n);sleep(1);}return 0;
}启动前台进程./mytest 或输入指令 启动后台进程./mytest 从下图可以看到我启动一个前台进程之后通过键盘输入的 ll 和 cd指令都不管用了。 启动后台进程我们程序也在显示器上打印但是输入的 ll 和 cd 指令可以执行。
在这里插入图片描述
前台进程可以使用信号的方式终止将程序启动为后台进程发现 ctrl c 发送信号不能终止进程使用jobs查看系统运行的任务 使用 fg 任务号将后台进程转成前台进程再通过 ctrl c终止进程
[xiyanhecs-34711 ~]$ jobs
[1] Running ./mytest (wd: ~/code/test)
[xiyanhecs-34711 ~]$ fg 1任务和进程的关系一个任务可以一个人完成也可多个人完成 一个任务可以是一个进程执行也可以是多个进程执行多个进程组成进程组以第一个进程的进程pid为任务号一个进程可以自成进程组通过查看PGID属性字段就能验证。
[xiyanhecs-34711 test]$ sleep 1000 | sleep 2000 | sleep 3000
[1] 6114
[xiyanhecs-34711 test]$ mytest log.txt
[2] 6141
[xiyanhecs-34711 test]$ jobs
[1]- Running sleep 1000 | sleep 2000 | sleep 3000
[2] Running ./mytest log.txt
[xiyanhecs-34711 test]$ ps axj | head -1 ps xj | grep sleepPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND4559 6112 6112 4559 pts/4 6267 S 1000 0:00 sleep 10004559 6113 6112 4559 pts/4 6267 S 1000 0:00 sleep 20004559 6114 6112 4559 pts/4 6267 S 1000 0:00 sleep 3000
[xiyanhecs-34711 test]$ ps axj | head -1 ps xj | grep mytestPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND4559 6141 6141 4559 pts/4 6285 S 1000 0:00 ./mytest会话的概念 Linux操作系统中当一个用户登录的时候会分配一个会话一个会话期间可以创建多个进程组退出登录会话会销毁会话中前台进程终止后台进程可能不会终止但是会受一定的影响。
一个会话有多个进程但是前台进程只有一个系统会让bash来充当前台进程如果启动一个前台进程就会将bash替换当我们自己启动的前台进程退出又将bash换上来
退出登录后再登录 , 我的Linux机器是直接就终止了我们程序如何解决——进程守护化
[xiyanhecs-34711 test]$ ./mytest log.txt
[1] 12130
[xiyanhecs-34711 test]$ jobs
[1] Running ./mytest log.txt
[xiyanhecs-34711 test]$ ps axj | head -1 ps axj | grep mytestPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
12035 12130 12130 12035 pts/3 12153 S 1000 0:00 ./mytest
12035 12154 12153 12035 pts/3 12153 R 1000 0:00 grep --colorauto mytest
[xiyanhecs-34711 ~]$ ps axj | head -1 ps axj | grep mytestPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
12181 12214 12213 12181 pts/3 12213 R 1000 0:00 grep --colorauto mytest什么是守护进程 将自成进程组自成会话的进程称为守护进程他的本质也是孤儿进程
让会话1创建一个守护进程当会话1退出守护进程不受影响 [xiyanhecs-34711 ~]$ man 2 setsid
[xiyanhecs-34711 ~]$ man daemon # 系统自带的方法参考代码
#pragma once#include iostream
#include cstdlib
#include unistd.h
#include signal.h
#include string
#include sys/types.h
#include sys/stat.h
#include fcntl.hconst std::string nullfile /dev/null;void Daemon(const std::string cwd )
{// 1. 忽略其他异常信号signal(SIGCLD, SIG_IGN);signal(SIGPIPE, SIG_IGN);signal(SIGSTOP, SIG_IGN);// 2. 将自己变成独立的会话if (fork() 0)exit(0);setsid();// 3. 更改当前调用进程的工作目录if (!cwd.empty())chdir(cwd.c_str());// 4. 标准输入标准输出标准错误重定向至/dev/nullint fd open(nullfile.c_str(), O_RDWR);if(fd 0){dup2(fd, 0);dup2(fd, 1);dup2(fd, 2);close(fd);}
}