最后的话
最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!
资料预览
给大家整理的视频资料:
给大家整理的电子书资料:
如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
操作系统在对我们的进程进行先描述,后组织的时候,会先将我们的程序的共有属性创建一个结构体,然后对我们的每一个进程创建一个结构体对象,这就是先描述的过程。接下来我们的操作系统会使用特性的数据结构(比如链表)将我们的结构体对象组织起来,这就是后组织的过程。然后我们的操作系统对进程的管理就会转换成对特定数据结构的管理。
所以,进程 = 内核关于进程的相关数据结构+当前进程的代码和数据。
task_ struct内容分类
- 标示符: 描述本进程的唯一标示符,用来区别其他进程;
- 状态: 任务状态,退出代码,退出信号等;
- 优先级: 相对于其他进程的优先级;
- 程序计数器: 程序中即将被执行的下一条指令的地址;
- 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针;
- 上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器];
- I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表;
- 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等;
- 其他信息。
3、组织进程
可以在内核源代码里找到它。所有运行在系统里的进程都以task_struct链表的形式存在内核里。
4、查看进程和终止
查看一个进程的基本信息,我们可以利用命令 ps -axj 列出当前系统所用进程信息;
先测试一段代码:
#include<stdio.h>
#include<unistd.h>
int main()
{
while(1)
{
printf("我是一个进程!\n");
sleep(1);
}
return 0;
}
在输入查看进程的命令,如下所示:
输入 ps -axj | head -1 && ps -axj | grep “test”,就可以获得表头及带有 test 的进程。
这里我们还需要解释一个概念那就是 PID 和 PPID 的概念,操作系统里指进程识别号,也就是进程表示符。操作系统里每打开一个程序都会创建一个进程 ID,即 PID 。 当然了,PPID 就是父进程的进程 ID 号。
杀死进程
有两种方法:第一种是Ctrl + c 是强制结束进程,第二种是:用命令的形式,kill -9 PID,指定目标进程杀死。
在这里我推荐使用第二种方法。
5、通过系统调用获取进程标识符
- 进程id(PID);
- 父进程id(PPID).
#include<iostream>
#include<sys/types.h>
#include<unistd.h>
using namespace std;
int main()
{
pid_t t = fork();
if (t == 0)
{
while (1)
{
cout << "我是一个子进程" << " pid:" << getpid() << " ppid:" << getppid() << endl;
sleep(1);
}
}
else if (t > 0)
{
while (1)
{
cout << "我是一个父进程" << " pid:" << getpid() << " ppid:" << getppid() << endl;
sleep(1);
}
}
return 0;
}
6、通过系统调用创建进程-fork
- 运行 man fork 认识 fork;
- fork有两个返回值;
- 父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝);
- fork 之后通常要用 if 进行分流。
可以看到 fork() 这个函数很特殊,成功创建子进程后居然有两个返回值,给父进程返回子进程pid,给子进程返回 0,如果创建失败那么就返回 -1。
如何理解两个返回值
当 fork() 要对值进行返回的时候,其实在函数的内部创建子进程的工作已经完成,此时已经有了两个进程,两个进程继续执行下面的语句,执行完 fork() 之后自然都会有返回值,这样在我们看来就好像有两个返回值,实则我们在接收返回值时便已触发了写时拷贝(写实拷贝就是当操作系统检测到子进程有写的操作的时候,操作系统就会给子进程分配相应的物理空间),看似相同的 ret 实则储存在不同的空间。
7、进程状态
- R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里;
- S睡眠状态(sleeping): 意味着进程在等待事件完成 (这里的睡眠有时候也叫做可中断睡眠 (interruptible sleep));
- D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的 进程通常会等待IO的结束;
- T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可 以通过发送 SIGCONT 信号让进程继续运行;
- X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态.
ps -axj 指令是查看进程的信息
(1)R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里;
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
while (1)
{
;
}
return 0;
}
运行时,查看进程的状态是R+,说明是运行状态。
后面有个+号表示什么意思呢?
这里+表示该进程是前台运行的,当我们使用ctrl+c的时候能够终止掉该进程,不写+表示的是后台运行的,这时用ctrl+c是无法终止掉该程序的,要用命令杀掉进程来终止。
(2)S睡眠状态(sleeping): 意味着进程在等待事件完成 (这里的睡眠有时候也叫做可中断睡眠 (interruptible sleep));
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
int n = 0;
scanf("%d", &n);
return 0;
}
运行时,查看进程的状态是S+,说明是睡眠状态。
(3)T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行;
kill -l :就能显示所有的信号,而 SIGSTOP 信号对应 19 ,SIGCONT 信号对应 18。
当我们输入kill -19 PID ,该进程就会处于停止状态。
当我们输入kill -18 PID ,该进程就会恢复状态。
(4)死亡状态:这个状态只是一个返回状态,是一瞬间的,你可能不会在任务列表里看到这个状态,因为一个进程死亡后就会变成僵尸进程。
(5)僵尸状态:进程死亡后的状态,一个进程死亡后,会处于僵尸状态如果其父进程不回收,会一直占用资源,造成内存泄漏。
8、特殊进程
8.1 僵尸进程
- 僵尸状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用) 没有读取到子进程退出的返回代码时就会产生僵尸进程。
- 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
- 只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态
下面演示一下僵尸进程:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
pid_t id = fork();
if (id == 0)
{
//子进程
while (1)
{
printf("我是子进程,我的pid :%d,我的ppid: %d\n", getpid(), getppid());
sleep(1);
}
}
else if (id > 0)
{
//父进程
while (1)
{
printf("我是父进程,我的pid :%d,我的ppid: %d\n", getpid(), getppid());
sleep(1);
}
}
else
{
perror("fail");
exit(-1);
}
return 0;
}
运行时,当中途用kill -9 PID 杀死子进程,此时子进程就是一个僵尸进程。
8.2 孤儿进程
- 父进程如果提前退出,那么子进程后退出,进入Z之后,那该如何处理呢?
- 父进程先退出,子进程就称之为“孤儿进程”
- 孤儿进程被1号init进程领养,当然要有init进程回收喽。
看下面这段代码,就是父进程先运行3秒,然后就退出了,此时子进程就是孤儿进程。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t id = fork();
if (id < 0)
{
perror("fail");
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(-1);
}
![](https://img-blog.csdnimg.cn/img_convert/9a8cb5f8c0ec69e6499adead0da6e95b.png)
最全的Linux教程,Linux从入门到精通
======================
1. **linux从入门到精通(第2版)**
2. **Linux系统移植**
3. **Linux驱动开发入门与实战**
4. **LINUX 系统移植 第2版**
5. **Linux开源网络全栈详解 从DPDK到OpenFlow**
![华为18级工程师呕心沥血撰写3000页Linux学习笔记教程](https://img-blog.csdnimg.cn/img_convert/59742364bb1338737fe2d315a9e2ec54.png)
第一份《Linux从入门到精通》466页
====================
内容简介
====
本书是获得了很多读者好评的Linux经典畅销书**《Linux从入门到精通》的第2版**。本书第1版出版后曾经多次印刷,并被51CTO读书频道评为“最受读者喜爱的原创IT技术图书奖”。本书第﹖版以最新的Ubuntu 12.04为版本,循序渐进地向读者介绍了Linux 的基础应用、系统管理、网络应用、娱乐和办公、程序开发、服务器配置、系统安全等。本书附带1张光盘,内容为本书配套多媒体教学视频。另外,本书还为读者提供了大量的Linux学习资料和Ubuntu安装镜像文件,供读者免费下载。
![华为18级工程师呕心沥血撰写3000页Linux学习笔记教程](https://img-blog.csdnimg.cn/img_convert/9d4aefb6a92edea27b825e59aa1f2c54.png)
**本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。**
> 需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
g.cn/img_convert/9d4aefb6a92edea27b825e59aa1f2c54.png)
**本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。**
> 需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**