不逼你自己一把,你怎么知道自己行不行
为了弄明白正在进行的进程是什么意思,究竟怎样才算正在运行的进程,比如说一个人的状态可能在工作也有可能在睡觉,那么我们进程也是也有着运行状态休眠状态。
那么首先我们要知道一个进程可以有几个状态,(在Linux内核中进程有时候也叫做任务)
下面的状态再kerne(包含内核管理的核心代码)l源代码里定义
/*
* 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 */
};
首先就是D状态也就是磁盘休眠状态这里的意思其实很简单也就是说在一个进程想要访问某个资源的时候而这些资源却不可用的时候那么该进程就会进入D状态,那么我给大家举一个列子,比如说A进程正在向文件中写入一个很大很大的数据,这时候B进程想要访问该文件可是该文件目前正在被写入数据那么此时B进程就需要先进入磁盘休眠状态来等待该文件的写入完成从而访问该文件。
S状态,s状态也叫做可唤醒睡眠状态那么此时我们就比较容易理解了,他和T状态是有不同的比如说T状态的进程你是不能唤醒的但是S状态的进程是可以被唤醒的比如说父进程创建了一个子进程并等待子进程结束,而子进程进入一个睡眠状态比如说sleep(10)等待10秒钟。在这期间,父进程通过 waitpid 等待子进程的结束。子进程虽然处于S状态,但如果收到信号(例如SIGCHLD),它会被中断并被唤醒。在实际情况中,进程可能会因为等待I/O操作、等待信号、等待锁或其他事件而进入可中断睡眠状态。在这种状态下,如果相应的事件发生或者进程收到中断信号,它就有可能被唤醒。这种状态对于系统的资源管理是很有用的,因为它允许系统更好地处理各个进程的资源需求
代码实列
#include <stdio.h>
#include <unistd.h>
int main() {
// 创建一个子进程
pid_t child_pid = fork();
if (child_pid == -1) {
perror("Error creating child process");
return 1;
}
if (child_pid == 0) {
// 子进程在这里执行
sleep(10);
return 0;
} else {
// 父进程在这里执行
// 父进程等待子进程结束
waitpid(child_pid, NULL, 0);
return 0;
}
}
T/t状态:这两种状态呢其实到了现在区别已经很少了,T:表示进程被停止,通常是由于接收到了SIGSTOP、SIGTSTP、SIGTTIN或SIGTTOU等信号。这种状态意味着进程暂时被挂起,不再执行,等待进一步的命令以继续执行。t:表示进程是一个跟踪进程(traced process)。通常,这是由调试器(如gdb)使用 ptrace 系统调用追踪的进程。被追踪的进程会在收到SIGSTOP信号时进入小写t状态。
命令:ps aux / ps axj 命令
下面这个图片是进程收到信号的一系列状态
int main()
{
pid_t id = fork(); if(id < 0){
perror("fork"); return 1; }
else if(id > 0){ //parent
printf("parent[%d] is sleeping...\n", getpid()); sleep(30);
}else{
printf("child[%d] is begin Z...\n", getpid());
sleep(5);
exit(EXIT_SUCCESS);
}
return 0;
}
进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。可父进程如果一直不读取,那子进程就一直处于Z状态?是的!
维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态一直不退出,PCB一直都要维护?是的!
那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空
间!
内存泄漏?是的!
父进程如果提前退出,那么子进程后退出,进入Z之后,那该如何处理呢?父进程先退出,子进程就称之为“孤儿进程”
孤儿进程被1号init进程领养,当然要有init进程回收喽。
int main()
{
pid_t id = fork();
if(id < 0){
perror("fork");
return 1;
}
else if(id == 0){//child
printf("I am child, pid : %d\n", getpid()); sleep(10);
}else{//parent
printf("I am parent, pid: %d\n", getpid()); sleep(3);
exit(0);
}
return 0;
}
cpu资源分配的先后顺序,就是指进程的优先权(priority)。
优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。