精华内容
下载资源
问答
  • 趣谈linux操作系统

    千次阅读 2019-08-31 18:07:53
    学习掌握linux原理[包括Linux 操作系统的基础知识], 理论指导实践, 以期达到熟悉地在linux下工作. 2. 学习 2.1 测试 https://blog.csdn.net/william_n/article/details/103886154 ...

    1. 应用背景

    学习掌握linux原理[包括Linux 操作系统的基础知识], 理论指导实践, 以期达到熟悉地在linux下工作.

    2. 学习

    Note:

    这里的文档可能并不是很详细, 很有节奏, 主要是作为个人笔记.

     

    文档原型:

    <<趣谈linux操作系统>> -- 极客时间

     

    介绍

    https://time.geekbang.org/column/article/87104  // 开篇词 | 为什么要学习Linux操作系统?

     

    2.1 测试

    https://blog.csdn.net/william_n/article/details/103886154

     

     

     

     

    后续补充

    ...

    3.实验/实践

    1.如何进入实模式

    https://github.com/icecoobe/oslab  // 参考 -- 20201103 周二

    4. 推荐书籍

    https://blog.csdn.net/william_n/article/details/102892833  //如何学习 Linux

     

    书籍视频资源推荐:

    <<鸟哥的Linux私房菜>>

    <<一个64位操作系统的设计与实现>>

    <<从实模式到保护模式>

    https://github.com/chyyuu/os_kernel_lab  // 清华大学 操作系统 - 实验课

     

    汇编语言:

    <<汇编从零开始到C语言>> --- 网易云课堂

     

    更多资料推荐:

    https://blog.csdn.net/william_n/article/details/102892833  // 如何学习 Linux

     

    某网友:

    看到很多人留言需要资料,我来推荐一本新书《一个64位操作系统的设计与实现》,如果你有汇编基础,很感兴趣底层的细节,可以看李忠的那本《从实模式到保护模式》

     

     

    某网友:

    另外还有一点,文件描述符不是面向操作系统的,而是针对进程的,所以同一个文件在不同的进程里可能会有不同的fd。其实换个理解方式就好懂了:因为操作系统里有太多的文件,一个进程大概率不需要知道所有的文件,所以每当进程用到文件的时候,就像系统要来这个文件,对进程来说,一个类似于数组的东西就可以管理到所有系统分配给他的文件,所以fd就是按照自然数顺序依次排列的,0表示标准输入,1是标准输出,2是标准错误,这三个是固定的,后面的用到就依次往后加。相当于是个下标index的概念。
    作者回复: 是的

     

    某网友:

    2019-04-07
    可以自己搭个opengork服务器,教程百度有,很方便的看linux 源代码
    作者回复: 赞

     

     

    美美
    2019-08-23
    上面推荐的国外的教材叫OSTEP(Operating System Three Easy Picies) 已经有中文版了,顶上去让大家知道:https://book.douban.com/subject/33463930

    作者原版免费 http://pages.cs.wisc.edu/~remzi/OSTEP/

     

     

    2019-04-03
    给大家推荐一个快速搭建各种版本 Linux 系统的开源软件,如果你电脑中安装了 docker ,可以通过浏览器访问你创建的 Linux 系统,这样子你就可以大胆的,实验各种命令了。比如 rm -rf */.
    连接: https://github.com/instantbox/instantbox/blob/master/docs/README-zh_cn.md

     

    某网友;

    搭建命令查看服务

    https://github.com/tldr-pages/tldr

     

    某网友:

    爬第三个坡,我推荐看一下《庖丁解牛Linux内核分析》(https://book.douban.com/subject/30350365/),跟着MOOC一起自己动手搭建Linux内核,相当于自己动手做面粉厂

     

    5.学习体会

    TBD

    6. 参考

    极客时间专栏:趣谈linux操作系统 --刘超 以及不记名网友的评论见解

    https://blog.csdn.net/william_n/article/details/102893551  //Linux 学习路线图

    https://blog.csdn.net/william_n/article/details/102892833  //如何学习 Linux

    后续补充

    ...

    这里写图片描述

    展开全文
  • Linux操作系统综述你可以把Linux内核当成一家软件外包公司的老板快速上手几个Linux命令...课程:趣谈Linux操作系统 你可以把Linux内核当成一家软件外包公司的老板 快速上手几个Linux命令:每家公司都有自己的黑话 ...


    课程:趣谈Linux操作系统

    03-你可以把Linux内核当成一家软件外包公司的老板

    04-快速上手几个Linux命令:每家公司都有自己的黑话

    Linux命令简写和全称
    Linux常见命令缩写
    我的实验环境win10下的wsl,
    互通的环境:
    C:\Users\zhangjiequan-home\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\rootfs\home\zjqroot

    cmd -h 查看简要帮助文档
    man cmd 查看详细帮助文档(man, manual pages,手册页)
    如 passwd -h;man passwd

    用户与密码

    passwd #Pass Word 改密码等,eg:passwd testname
    useradd #加用户 eg:user add testname
    su [username] #Swith user  切换用户 eg:su root, su testname
    

    Windows 10 WSL Ubuntu 系统的 root 密码
    cat /etc/passwd
    cat /etc/group

    浏览文件

    cd就是change directory,就是切换目录;
    cd .表示切换到当前目录;
    cd …表示切换到上一级目录;
    ls,list (win使用dir),可以列出当前目录下的文件。
    ls -a
    ls -l 用列表的方式列出文件

    # ls -l
    drwxr-xr-x 6 root root    4096 Oct 20  2017 apt
    -rw-r--r-- 1 root root     211 Oct 20  2017 hosts
    

    第一个字段的第一个字符是文件类型。如果是“-”,表示普通文件;如果是d,就表示目录。当然还有很多种文件类型,咱们后面遇到的时候再说,你现在先记住我说的这两个就行了。

    第一个字段剩下的9个字符是模式,其实就是权限位(access permission bits)。
    3个一组,每一组rwx表示“读(read)”“写(write)”“执行(execute)”。
    如果是字母,就说明有这个权限;如果是横线,就是没有这个权限。

    这三组分别表示文件所属的用户权限、文件所属的组权限以及其他用户的权限。例如,上面的例子中,-rw-r–r–就可以翻译为,这是一个普通文件,对于所属用户,可读可写不能执行;对于所属的组,仅仅可读;对于其他用户,也是仅仅可读。如果想改变权限,可以使用命令chmod 711 hosts(Change mode 改变模式)。

    第二个字段是硬链接(hard link)数目,这个比较复杂,讲文件的时候我会详细说。
    第三个字段是所属用户,第四个字段是所属组。
    第五个字段是文件的大小,第六个字段是文件被修改的日期,最后是文件名。你可以通过命令chown改变所属用户,chgrp改变所属组。

    安装软件

    原始的下载安装包安装的方式(rpm/dpkg)

    RPM:Red hat package manager
    dpkg:Debian package manage(是 Debian 的项目创始人 Ian Murdock 和他的妻子 Debra 的名字缩写。;是Linux的一个版本。;Debian 是一套为了您的计算机所设计的自由操作系统。Debian 使用 Linux 核心;但大部份的基本工具则来自 GNU 计划;)
    在这里插入图片描述
    类似win下的exe,可以下载rpm或者deb。这个就是Linux下面的安装包。

    为什么有两种呢?因为Linux现在常用的有两大体系,一个是CentOS体系,一个是Ubuntu体系,前者使用rpm,后者使用deb。

    在Linux上面,没有双击安装这一说,因此想要安装,我们还得需要命令。CentOS下面使用rpm -i jdk-XXX_linux-x64_bin.rpm进行安装,Ubuntu下面使用dpkg -i jdk-XXX_linux-x64_bin.deb。其中-i就是install的意思。

    查看已安装的软件

    在Linux下面,凭借rpm -qadpkg -l就可以查看安装的软件列表,-q就是query,a就是all,-l的意思就是list。
    如果真的去运行的话,你会发现这个列表很长很长,很难找到你安装的软件。

    从多个结果中找到你要的
    grep

    如果你知道要安装的软件包含某个关键词,可以用一个很好用的搜索工具grep

    rpm -qa | grep jdk,这个命令是将列出来的所有软件形成一个输出。| 是管道,用于连接两个程序,前面rpm -qa的输出就放进管道里面,然后作为grep的输入,grep将在里面进行搜索带关键词jdk的行,并且输出出来。grep支持正则表达式,因此搜索的时候很灵活,再加上管道,这是一个很常用的模式。同理dpkg -l | grep jdk也是能够找到的。

    more/less

    如果你不知道关键词,可以使用rpm -qa | more和rpm -qa | less这两个命令,它们可以将很长的结果分页展示出来。这样你就可以一个个来找了。

    我们还是利用管道的机制。more是分页后只能往后翻页,翻到最后一页自动结束返回命令行,less是往前往后都能翻页,需要输入q返回命令行,q就是quit。

    删除软件

    如果要删除,可以用rpm -e和dpkg -r。-e就是erase,-r就是remove。

    "软件管家"yum/apt

    yum,yellowdog updater modified 的缩写。yellowdog 是一个 Linux 的 distribution。
    apt,Advanced Packaging Tool

    搜索

    你可以根据关键词搜索,例如搜索jdk、yum search jdk和apt-cache search jdk(apt search jdk),可以搜索出很多很多可以安装的jdk版本。如果数目太多,你可以通过管道grep、more、less来进行过滤。

    安装

    选中一个之后,我们就可以进行安装了。你可以用yum install java-11-openjdk.x86_64和apt-get install openjdk-9-jdk来进行安装。

    卸载

    安装以后,如何卸载呢?我们可以使用yum erase java-11-openjdk.x86_64和apt-get purge openjdk-9-jdk。

    服务端地址

    Linux允许我们配置从哪里下载这些软件的,地点就在配置文件里面。

    对于CentOS来讲,配置文件在/etc/yum.repos.d/CentOS-Base.repo里。

    [base]
    name=CentOS-$releasever - Base - 163.com
    baseurl=http://mirrors.163.com/centos/$releasever/os/$basearch/
    gpgcheck=1
    gpgkey=http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-7
    

    对于Ubuntu来讲,配置文件在/etc/apt/sources.list里。

    deb http://mirrors.163.com/ubuntu/ xenial main restricted universe multiverse
    deb http://mirrors.163.com/ubuntu/ xenial-security main restricted universe multiverse
    deb http://mirrors.163.com/ubuntu/ xenial-updates main restricted universe multiverse
    deb http://mirrors.163.com/ubuntu/ xenial-proposed main restricted universe multiverse
    deb http://mirrors.163.com/ubuntu/ xenial-backports main restricted universe multiverse
    

    注意改后需要执行apt update

    这里为什么都是163.com呢?因为Linux服务器遍布全球,不能都从一个地方下载,最好选一个就近的地方下载,例如在中国,选择163.com,就不用跨越重洋了。

    sed命令的使用

    Linux命令大全-sed命令
    Linux sed 命令

    使用sed更换apt源

    WSL-Ubuntu18.04 LTS 更换apt源为阿里源

    安装软件的本质

    其实无论是先下载再安装,还是通过软件管家进行安装,都是下载一些文件,然后将这些文件放在某个路径下,然后在相应的配置文件中配置一下。例如,在Windows里面,最终会变成C:\Program Files下面的一个文件夹以及注册表里面的一些配置。对应Linux里面会放的更散一点。例如,
    主执行文件:会放在/usr/bin或者/usr/sbin下面,
    其他的库文件:会放在/var下面,
    配置文件:会放在/etc下面。

    最原始的安装方式

    所以其实还有一种简单粗暴的方法,就是将安装好的路径直接下载下来,然后解压缩成为一个整的路径。在JDK的安装目录中,Windows有jdk-XXX_Windows-x64_bin.zip,这是Windows下常用的压缩模式。Linux有jdk-XXX_linux-x64_bin.tar.gz,这是Linux下常用的压缩模式。

    下载

    如何下载呢?Linux上面有一个工具wget,后面加上链接,就能从网上下载了。

    解压

    下载下来后,我们就可以进行解压缩了。Windows下可以有winzip之类的解压缩程序,Linux下面默认会有tar程序。如果是解压缩zip包,就需要另行安装。

    yum install zip.x86_64 unzip.x86_64
    apt-get install zip unzip
    

    如果是tar.gz这种格式的,通过tar xvzf jdk-XXX_linux-x64_bin.tar.gz就可以解压缩了。

    关于解压的相关命令的补充

    Linux 学习之创建、删除文件和文件夹命令
    六、Linux常用命令之压缩打包篇(gzip、gunzip、tar、zip、bzip2)
    1、gzip有两个特点:
    (1)、它只能压缩文件,不能压缩目录
    (2)、不保留源文件 newfile1.gz newfile1不在了
    看起来没什么用,过时的产物?
    gunzip和gzip是一对,压缩和解压
    2、tar

    tar -zcf filename.tar.gz ./* #压缩当前目录下的所有文件
    tar -zxvf ./filename.tar.gz -C ./b #解压在目录C下
    

    不产生后缀名,一般手动指定为*.tar.gz(用file a.tar.gz会有提示gzip compressed data,不指定后缀,无法通过ls直观看到文件类型)
    3、压缩解压命令zip (注意:该命令不自动产生后缀名,会保留源文件,用得最多的压缩命令,但不是自带,可以用sudo apt install zip等安装)

    zip services.zip /etc/services
    unzip services.zip -b ./disDic
    

    4、压缩解压命令:bzip2(不能压缩目录,但由于有-k选项,所以可以保留源文件)

    设置环境变量

    win上设置环境变量
    对于Windows上jdk的安装,如果采取这种下载压缩包的格式,需要在系统设置的环境变量配置里面设置JAVA_HOME和PATH。
    在Linux也是一样的,通过tar解压缩之后,也需要配置环境变量

    export(仅在当前命令行的会话中管用)

    可以通过export命令来配置

    export JAVA_HOME=/root/jdk-XXX_linux-x64
    export PATH=$JAVA_HOME/bin:$PATH
    

    export命令仅在当前命令行的会话中管用,一旦退出重新登录进来,就不管用了。

    .bashrc(每次登录都会执行)

    有没有一个地方可以像Windows里面可以配置永远管用呢?

    在当前用户的默认工作目录,例如/root或者/home/cliu8下面,有一个.bashrc文件,这个文件是以点开头的,这个文件默认看不到,需要ls -la才能看到,a就是all。每次登录的时候,这个文件都会运行,因而把它放在这里。这样登录进来就会自动执行。当然也可以通过source .bashrc手动执行。

    要编辑.bashrc文件,可以使用文本编辑器vi,也可以使用更加友好的vim。如果默认没有安装,可以通过yum install vim及apt-get install vim进行安装。

    运行软件

    我们都知道Windows下的程序,如果后缀名是exe,双击就可以运行了。

    通过shell在交互命令行里面运行

    Linux不是根据后缀名来执行的。它的执行条件是这样的:只要文件有x执行权限,都能到文件所在的目录下,通过./filename运行这个程序。当然,如果放在PATH里设置的路径下面,就不用./了,直接输入文件名就可以运行了,Linux会帮你找。

    这是Linux执行程序最常用的一种方式,通过shell在交互命令行里面运行。

    这样执行的程序可能需要和用户进行交互,例如允许让用户输入,然后输出结果也打印到交互命令行上。这种方式比较适合运行一些简单的命令,例如通过date获取当前时间。这种模式的缺点是,一旦当前的交互命令行退出,程序就停止运行了。

    这样显然不能用来运行那些需要“永远“在线的程序。比如说,运行一个博客程序,我总不能老是开着交互命令行,博客才可以提供服务。一旦我要去睡觉了,关了命令行,我的博客别人就不能访问了,这样肯定是不行的。

    后台运行

    于是,我们就有了Linux运行程序的第二种方式,后台运行。

    nohup

    这个时候,我们往往使用nohup命令。这个命令的意思是no hang up(不挂起),也就是说,当前交互命令行退出的时候,程序还要在。

    当然这个时候,程序不能霸占交互命令行,而是应该在后台运行。最后加一个&,就表示后台运行:

    nohup command &
    

    输出

    另外一个要处理的就是输出,原来什么都打印在交互命令行里,现在在后台运行了,输出到哪里呢?输出到文件是最好的。

    最终命令的一般形式为nohup command >out.file 2>&1 &
    解释一下其中新增的>out.file 2>&1
    这里面,“1”表示文件描述符1,表示标准输出,“2”表示文件描述符2,意思是标准错误输出,“2>&1”表示标准输出和错误输出合并了。合并到哪里去呢?到out.file里。

    关闭进程

    那这个进程如何关闭呢?我们假设启动的程序包含某个关键字,那就可以使用下面的命令。

    ps -ef |grep 关键字  |awk '{print $2}'|xargs kill -9
    

    从这个命令中,我们多少能看出shell的灵活性和精巧组合。

    其中:
    ps -ef:可以单独执行,列出所有正在运行的程序
    grep:上面我们介绍过了,通过关键字找到咱们刚才启动的程序。
    awk:工具可以很灵活地对文本进行处理,这里的awk '{print $2}'是指第二列的内容,是运行的程序ID。
    xargs kill -9:我们可以通过xargs传递给kill -9,也就是发给这个运行的程序一个信号,让它关闭。如果你已经知道运行的程序ID,可以直接使用kill关闭运行的程序。如使用ps -ef得到进程id为576,可使用kill -9 576来关闭这个进程。(一开始对这个xargs kill -9不懂,看了Linux中的管道和xargs之后,补充一下:xargs kill -9前面的一坨东东,其实就是得到了一个进程id,最后用xargs把id传给kill -9,效果是kill -9 ${id})

    以服务的方式运行

    在Windows里面还有一种程序,称为服务。这是系统启动的时候就在的,我们可以通过控制面板的服务管理启动和关闭它。
    在这里插入图片描述
    Linux也有相应的服务,这就是程序运行的第三种方式,以服务的方式运行。例如常用的数据库MySQL,就可以使用这种方式运行。

    例如在Ubuntu中,我们可以通过apt-get install mysql-server的方式安装MySQL,然后通过命令systemctl start mysql启动MySQL,通过systemctl enable mysql设置开机启动。之所以成为服务并且能够开机启动,是因为在/lib/systemd/system目录下会创建一个XXX.service的配置文件,里面定义了如何启动、如何关闭。

    在CentOS里有些特殊,MySQL被Oracle收购后,因为担心授权问题,改为使用MariaDB,它是MySQL的一个分支。通过命令yum install mariadb-server mariadb进行安装,命令systemctl start mariadb启动,命令systemctl enable mariadb设置开机启动。同理,会在/usr/lib/systemd/system目录下,创建一个XXX.service的配置文件,从而成为一个服务。

    即无论Ubuntu还是CentOS,用都是用systemctl启动和设置开机启动。

    (wsl下的Ubuntu不能用systemctl,启动可以用:

    sudo service mysql start
    

    开机启动暂时不知道怎么搞。
    解决Win10-Ubuntu子系统启动MySQL报错的问题
    System has not been booted with systemd as init system (PID 1). Can’t operate

    systemd的机制十分复杂,这里咱们不讨论。如果有兴趣,你可以自己查看相关文档。

    关机与重启

    最后咱们要学习的是如何关机和重启。这个就很简单啦。shutdown -h now是现在就关机,reboot就是重启。

    (wsl下重启:

    net stop LxssManager
    net start LxssManager
    

    关机自然是:

    net stop LxssManager
    

    ref:如何重启 Windows 10 子系统(WSL) ubuntu)

    小结

    在这里插入图片描述

    05-学会几个系统调用:咱们公司能接哪些类型的项目?

    其实Linux命令也是一个程序,只不过代码是别人写好的,你直接用就可以了。你可以自己试着写写代码,通过代码把Linux系统用起来,这样印象会更深刻。

    无论是别人写的程序,还是你写的程序,运行起来都是进程。程序使用的是系统调用,系统调用决定了这个操作系统好用不好用、功能全不全。下面介绍都有哪些”系统调用“:

    进程管理

    首先,我们得有个项目,那就要有立项服务。对应到Linux操作系统中就是创建进程。

    创建进程的系统调用叫fork。这个名字很奇怪,中文叫“分支”。为啥启动一个新进程叫“分支”呢?

    在Linux里,要创建一个新的进程,需要一个老的进程调用fork来实现,其中老的进程叫作父进程(Parent Process),新的进程叫作子进程(Child Process)。

    当父进程调用fork创建进程的时候,子进程将各个子系统为父进程创建的数据结构也全部拷贝了一份,甚至连程序代码也是拷贝过来的。按理说,如果不进行特殊的处理,父进程和子进程都按相同的程序代码进行下去,这样就没有意义了。

    所以,我们往往会这样处理:对于fork系统调用的返回值,如果当前进程是子进程,就返回0;如果当前进程是父进程,就返回子进程的进程号。这样首先在返回值这里就有了一个区分,然后通过if-else语句判断,如果是父进程,还接着做原来应该做的事情;如果是子进程,需要请求另一个系统调用-execve来执行另一个程序,这个时候,子进程和父进程就彻底分道扬镳了,也即产生了一个分支(fork)了。

    同样是“先拷贝,再修改”的策略,你可能会问,新进程都是父进程fork出来的,那到底谁是第一个呢?

    启动的时候先创建一个所有用户进程的“祖宗进程”。这个在讲系统启动的时候还会详细讲,我这里先不多说。

    有时候,父进程要关心子进程的运行情况,这毕竟是自己身上掉下来的肉。有个系统调用-waitpid,父进程可以调用它,将子进程的进程号作为参数传给它,这样父进程就知道子进程运行完了没有,成功与否。

    所以说,所有子项目最终都是老板,也就是祖宗进程fork过来的,因而它要对整个公司的项目执行负最终的责任。

    内存管理

    在操作系统中,每个进程都有自己的内存,互相之间不干扰,有独立的进程内存空间

    对于进程的内存空间来讲,放程序代码的这部分,我们称为代码段(Code Segment)

    对于进程的内存空间来讲,放进程运行中产生数据的这部分,我们称为数据段(Data Segment)。其中局部变量的部分,在当前函数执行的时候起作用,当进入另一个函数时,这个变量就释放了(栈?);也有动态分配的,会较长时间保存,指明才销毁的,这部分称为堆(Heap)

    一个进程的内存空间是很大的,32位的是4G,64位的就更大了,我们不可能有这么多物理内存。就像一个公司的会议室是有限的,作为老板,你不可能事先都给项目组分配好。哪有这么多会议室啊,一定是需要的时候再分配。

    所以,进程自己不用的部分就不用管,只有进程要去使用部分内存的时候,才会使用内存管理的系统调用来登记,说自己马上就要用了,希望分配一部分内存给它,但是这还不代表真的就对应到了物理内存。只有真的写入数据的时候,发现没有对应物理内存,才会触发一个中断,现分配物理内存。

    这里我们介绍两个在堆里面分配内存的系统调用,brkmmap

    当分配的内存数量比较小的时候,使用brk,会和原来的堆的数据连在一起,这就像多分配两三个工位,在原来的区域旁边搬两把椅子就行了。当分配的内存数量比较大的时候,使用mmap,会重新划分一块区域,也就是说,当办公空间需要太多的时候,索性来个一整块。

    文件管理

    程序、文档、照片等,哪怕Linux关机再开机也能不丢的,就需要放在文件系统里面。

    文件之所以能做到这一点,一方面是因为介质,另一方面是因为格式。公司之所以强调资料库,也是希望将一些知识固化为标准格式,放在一起进行管理,无论多少人来人走,都不影响公司业务。

    文件管理其实花样不多,拍着脑袋都能想出来,无非是创建、打开、读、写等。
    对于文件的操作,下面这六个系统调用是最重要的:

    • 对于已经有的文件,可以使用open打开这个文件,close关闭这个文件;
    • 对于没有的文件,可以使用creat创建文件;
    • 打开文件以后,可以使用lseek跳到文件的某个位置;
    • 可以对文件的内容进行读写,读的系统调用是read,写是write

    但是别忘了,Linux里有一个特点,那就是一切皆文件

    • 启动一个进程,需要一个程序文件,这是一个二进制文件
    • 启动的时候,要加载一些配置文件,例如yml、properties等,这是文本文件;启动之后会打印一些日志,如果写到硬盘上,也是文本文件
    • 但是如果我想把日志打印到交互控制台上,在命令行上唰唰地打印出来,这其实也是一个文件,是标准输出stdout文件
    • 这个进程的输出可以作为另一个进程的输入,这种方式称为管道,管道也是一个文件。
    • 进程可以通过网络和其他进程进行通信,建立的Socket,也是一个文件。
    • 进程需要访问外部设备,设备也是一个文件。
    • 文件都被存储在文件夹里面,其实文件夹也是一个文件。
    • 进程运行起来,要想看到进程运行的情况,会在/proc下面有对应的进程号,还是一系列文件。

    每个文件,Linux都会分配一个文件描述符(File Descriptor),这是一个整数。有了这个文件描述符,我们就可以使用系统调用,查看或者干预进程运行的方方面面

    所以说,文件操作是贯穿始终的,这也是“一切皆文件”的优势,就是统一了操作的入口,提供了极大的便利。

    信号处理

    在项目运行过程中,不一定都是一帆风顺的,很可能遇到各种异常情况。作为老板,处理异常情况的能力是非常重要的,所以办事大厅也一定要包含这部分服务。

    当项目遇到异常情况,例如项目中断,做到一半不做了。这时候就需要发送一个信号(Signal)给项目组。经常遇到的信号有以下几种:

    • 在执行一个程序的时候,在键盘输入“CTRL+C”,这就是中断的信号,正在执行的命令就会中止退出;
    • 如果非法访问内存,例如你跑到别人的会议室,可能会看到不该看的东西;
    • 硬件故障,设备出了问题,当然要通知项目组;
    • 用户进程通过kill函数,将一个用户信号发送给另一个进程。

    当项目组收到信号的时候,项目组需要决定如何处理这些异常情况。

    对于一些不严重的信号,可以忽略,该干啥干啥,但是像SIGKILL(用于终止一个进程的信号)和SIGSTOP(用于中止一个进程的信号)终?中?区别??是不能忽略的,可以执行对于该信号的默认动作。每种信号都定义了默认的动作,例如硬件故障,默认终止;也可以提供信号处理函数,可以通过sigaction系统调用,注册一个信号处理函数。

    提供了信号处理服务,项目执行过程中一旦有变动,就可以及时处理了。

    进程间通信

    消息队列(Message Queue)

    首先就是发个消息,不需要一段很长的数据,这种方式称为消息队列(Message Queue)。由于一个公司内的多个项目组沟通时,这个消息队列是在内核里的,我们可以通过msgget创建一个新的队列,msgsnd将消息发送到消息队列,而消息接收方可以使用msgrcv从队列中取消息。

    共享内存

    当两个项目组需要交互的信息比较大的时候,可以使用共享内存的方式,也即两个项目组共享一个会议室(这样数据就不需要拷贝来拷贝去)。大家都到这个会议室来,就可以完成沟通了。这时候,我们可以通过shmget创建一个共享内存块,通过shmat将共享内存映射到自己的内存空间,然后就可以读写了。

    信号量机制Semaphore

    但是,两个项目组共同访问一个会议室里的数据,就会存在“竞争”的问题。如果大家同时修改同一块数据咋办?这就需要有一种方式,让不同的人能够排他地访问,这就是信号量的机制Semaphore。

    这个机制比较复杂,我这里说一种简单的场景。

    对于只允许一个人访问的需求,我们可以将信号量设为1。当一个人要访问的时候,先调用sem_wait。如果这时候没有人访问,则占用这个信号量,他就可以开始访问了。如果这个时候另一个人要访问,也会调用sem_wait。由于前一个人已经在访问了,所以后面这个人就必须等待上一个人访问完之后才能访问。当上一个人访问完毕后,会调用sem_post将信号量释放,于是下一个人等待结束,可以访问这个资源了。

    公司间沟通与网络通信

    同一个公司不同项目组之间的合作搞定了,如果是不同公司之间呢?也就是说,这台Linux要和另一台Linux交流,这时候,我们就需要用到网络服务。

    不同机器的通过网络相互通信,要遵循相同的网络协议,也即TCP/IP网络协议栈。Linux内核里有对于网络协议栈的实现。如何暴露出服务给项目组使用呢?

    网络服务是通过套接字Socket来提供服务的。Socket这个名字很有意思,可以作“插口”或者“插槽”讲。虽然我们是写软件程序,但是你可以想象成弄一根网线,一头插在客户端,一头插在服务端,然后进行通信。因此,在通信之前,双方都要建立一个Socket。

    我们可以通过Socket系统调用建立一个Socket。Socket也是一个文件,也有一个文件描述符,也可以通过读写函数进行通信。

    好了,我们分门别类地规划了这么多办事大厅的服务,如果这些都有了,足够我们成长为一个大型跨国公司了。

    查看源代码中的系统调用

    你如果问,这里的系统调用列举全了吗?其实没有,系统调用非常多。我建议你访问https://www.kernel.org下载一份Linux内核源代码。因为在接下来的整个课程里,我讲述的逻辑都是这些内核代码的逻辑。
    (

    sudo lsb_release -a
    cat /proc/version
    

    ubuntu查看系统版本和linux内核版本)

    对于64位操作系统,找到unistd_64.h文件,里面对于系统调用的定义,就是下面这样。

    #define __NR_restart_syscall	  0
    #define __NR_exit		  1
    #define __NR_fork		  2
    #define __NR_read		  3
    #define __NR_write		  4
    #define __NR_open		  5
    #define __NR_close		  6
    #define __NR_waitpid		  7
    #define __NR_creat		  8
    ......
    

    中介与Glibc

    如果你做过开发,你会觉得刚才讲的和平时咱们调用的函数不太一样。这是因为,平时你并没有直接使用系统调用。虽然咱们的办事大厅已经很方便了,但是为了对用户更友好,我们还可以使用中介Glibc,有事情找它就行,它会转换成为系统调用,帮你调用。

    Glibc是Linux下使用的开源的标准C库,它是GNU发布的libc库。Glibc为程序员提供丰富的 API,除了例如字符串处理、数学运算等用户态服务之外,最重要的是封装了操作系统提供的系统服务,即系统调用的封装

    每个特定的系统调用对应了至少一个Glibc封装的库函数,比如说,系统提供的打开文件系统调用sys_open对应的是Glibc中的open函数

    有时候,Glibc一个单独的API可能调用多个系统调用,比如说,Glibc提供的printf函数就会调用如sys_open、sys_mmap、sys_write、sys_close等等系统调用。

    也有时候,多个API也可能只对应同一个系统调用,如Glibc下实现的malloc、calloc、free等函数用来分配和释放内存,都利用了内核的sys_brk的系统调用。

    小结

    学了这么多系统调用,我们还是用一个图来总结一下。
    在这里插入图片描述

    课堂练习

    有个命令strace,常用来跟踪进程执行时系统调用和所接收的信号。你可以试一下咱们学过的命令行,看看都执行了哪些系统调用。
    答:
    使用以下命令查看ls -la来跟踪这个命令执行时的系统调用和所接收的信号。

    strace ls -la
    

    执行后,得知有如下系统调用:
    execve
    brk
    mmap
    access
    open
    fstat
    mmap
    close
    read
    stat
    write
    lseek
    lstat
    getxattr
    socket
    connect
    mprotect

    展开全文
  • 趣谈Linux操作系统 原文链接:https://blog.csdn.net/shijinghan1126/article/details/111162704 一、操作系统概述 学习路径:爬过这六个陡坡,你就能对Linux了如指掌 03 | 你可以把Linux内核当成一家软件外包...

    趣谈Linux操作系统

    原文链接:https://blog.csdn.net/shijinghan1126/article/details/111162704

    一、操作系统概述

    学习路径:爬过这六个陡坡,你就能对Linux了如指掌

    在这里插入图片描述

    03 | 你可以把Linux内核当成一家软件外包公司的老板

    操作系统其实就像一个软件外包公司,其内核就相当于这家外包公司的老板。将自己的角色切换成这家软件外包公司的老板,设身处地地去理解操作系统是如何协调各种资源,帮客户做成事情的。
    在这里插入图片描述
    在这里插入图片描述
    从点击 QQ 图标,看操作系统全貌
    1、输入设备–接待人员
    鼠标和键盘是计算机的输入设备,在操作系统中,输入设备驱动其实就是客户对接员。有时候新插上一个鼠标的时候,会弹出一个通知你安装驱动,这就是操作系统这家外包公司给你配备对接人员呢。
    2、输出设备–交付人员
    显示器是输出设备,把计算机的处理结果呈现给客户。
    显卡会有显卡驱动,在操作系统中称为输出设备驱动,可以比喻成"交付人员“。
    3、中断事件
    客户提需求时,客户希望外包公司把正在做的事情停下来,服务他,这时客户发送的需求被称为”中断事件“。当鼠标双击QQ时,会触发一个中断,这相当于客户告知对接员,我有新需求,需要你给处理下。你会事先把处理这种问题的方法教给客户端对接员,这在操作系统里就是调用中断处理函数。
    4、程序-项目执行计划书
    对于使用QQ,对外部公司来说,相当于接了个新业务,需要有一个项目执行计划书。内容就是,对于QQ程序来说,他能做哪些事,每件事怎样做,先做什么后做什么,把上面的逻辑都写到程序里,这个程序就相当于项目执行计划书。
    5、文件管理系统
    硬盘是个物理设备,要格式化成文件系统,才能存放程序。文件系统需要一个系统统一管理,这个系统成为文件管理系统。
    6、程序&进程
    QQ的二进制文件是静态的,成为程序。而运行起来的QQ,成为进程。
    7、系统调用(System Call)
    当多个进程想要用打印机来打印文件,他们不能打印到同一张纸上,否则第一行是A进程输出的内容,第二行是B进程输出的内容,这样就乱了。所以,打印机的行为是由操作系统内核来统一管理的,进程不能直接操作,这个由操作系统统一管理的就是系统调用。

    系统调用会列出提供了哪些接口可以调用,然后进程在有需要的时候去调用。任何一个程序要运行起来,都需要通过系统调用来创建进程。
    8、进程管理系统
    在操作系统中,进程的执行也需要分配CPU来执行,所以,为了管理进程,我们还需要一个进程管理系统。如果运行的进程很多,则一个CPU会并发地运行多个进程,这就需要CPU的调度能力了。
    9、内存管理系统
    在操作系统中,不同的进程有不同的内存空间,这些内存空间需要统一的管理和分配,这就需要内存管理系统。

    04 | 快速上手几个Linux命令:每家公司都有自己的黑话

    在这里插入图片描述

    05 | 学会几个系统调用:咱们公司能接哪些类型的项目?

    在这里插入图片描述

    1、Fork
    在Linux里,要创建一个新的进程,需要一个老的进程调用fork来实现,这个老的进程叫做父进程,新的进程叫做子进程。
    2、进程的内存空间
    在操作系统里,每个进程都有自己的内存空间,不同进程之间互不干扰。

    代码段(Code segment):对于进程空间,放程序代码的部分,称为代码段。

    数据段(data segment):对于进程空间,存放进程运行中产生数据的部分,称为数据段。

    堆(Heap):其中局部变量部分,在当前函数运行的时候起作用,当进入另一个函数时,这个变量就释放了;也有动态分配的,会较长时间保留,指明才销毁的,这部分内存空间称为“堆”。
    3、brk和mmap
    当内存分配数量较小时,用brk,会和原来的堆的数据连在一起。
    当分配的内存较大时,使用mmap,会重新划分一块区域。
    4、文件管理
    Linux系统,一切皆文件:
    1)启动一个进程,需要一个二进制文件。
    2)启动进程时,需要加载一些配置文件如yml, properties等,这是文本文件
    3)把日志打印到控制台上,是标准输出stdout文件
    4)一个进程的输出作为另一个进程的输入,称为管道,管道也是一个文件
    5)进程可以通过网络和其他进程通信,建立的socket,也是一个文件
    6)进程需要访问的外部设备,也是一个文件
    7)文件夹也是一个文件

    每个文件,Linux都会分配一个文件描述符(File Descriptor),这是一个整数。有了这个文件描述符,我们就可以使用系统调用,查看或干预进程运行的方方面面。
    5、信号处理 – 项目异常处理
    通常进程中断,需要发送一个信号(signal),经常遇到的情况如下:
    1)“Ctrl + C", 执行的命令终止退出
    2)非法内存访问
    3)硬件故障
    4)用户进程通过kill函数,将信号发给另一个进程
    6、进程间通信 – 项目组间沟通
    1)消息队列:当两个进程需要交互的消息内容小的情况
    2)共享内存:当两个进程需要交互的信息量比较大,用共享内存方式,可通过shmget创建一个共享内存块,通过shmat将共享内存映射到自己的内存空间,就可以读写了。

    但是,当两个进程共同访问同一个内存中的数据时,就会存在竞争的问题。解决方式就是”排他“,通过信号量机制Semaphore。

    Semaphore机制简介:对于只允许一个人访问的需求,可将信号量设为1。当一个人要访问时,先调用sem_wait,这时如果没有人在访问,则他就占用这个信号量,他就可以开始访问了;如果此时也有另一人要访问,也调用了sem_wait。这时后一人必须等待前一人访问完才能访问。当一人访问完成后,会调用seg_post将信号量释放,下一个等待的人就可以访问这个资源了。
    7、网络通信-- 公司间沟通
    不同机器间通过网络通信才能交互,交互时通过遵循相同的网络协议,如TCP/IP。
    网络服务是通过Socket提供服务的,Socket可以理解为”插口“,在通信之前,双方要建立一个Socket。Socket也是一个文件,也有一个文件描述符,也可以通过读写函数进行通信。
    8、Glibc – 中介
    Glibc是Linux下使用开源的标准C库,Glibc为程序员提供丰富的API,除了如字符串处理、数学运算等用户态服务外,还封装了操作系统提供的系统服务,即系统调用的封装。

    二、Linux核心原理:系统初始化

    06 | x86架构:有了开放的架构,才能打造开放的营商环境

    在这里插入图片描述
    计算机硬件图:
    在这里插入图片描述
    CPU:对计算机来讲,CPU就是大脑,他是真正干活的,所有设备的执行都围绕他展开。

    总线(Bus):CPU和其他设备连接,通过总线,其实就是主板上密密麻麻的集成电路,这些组成了CPU和其他设备的高速通道。

    内存:在所有设备中,最重要的是内存(Memory),因为单靠CPU是无法完成计算任务的,很多复杂的计算需要把中间结果保持起来,然后基于中间结果做进一步的计算,所以CPU要依赖于内存。

    总线上还有一些其他设备,例如显卡会连接显示器,磁盘控制器会连接硬盘,USB控制器会连接键盘和鼠标等。

    CPU也不是单纯的一块,他包括三个部分:运算单元、数据单元、控制单元。
    1)运算单元:只管计算,不管结果存哪里
    2)数据单元:如果中间结果都存到数据里,那么每次计算都要经过总线去内存中拿,这太慢了,所以有了数据单元。数据单元包括CPU内部的缓存和寄存器组,空间很小,但速度飞快,可以暂时存放数据和运算结果。
    3)控制单元:用来指挥到底做什么运算。他是一个统一的指挥中心,他可以获得下一条指令,然后执行这条指令。这个指令会知道运算单元取出数据单元中的某几个数据,计算出结果,然后放在数据单元的什么地方。
    在这里插入图片描述
    程序运行过程中要操作的数据和产生的计算结果,都会放在数据段里面。那CPU怎么执行这些程序,操作这些数据,产生一些结果,并写入到内存呢?

    CPU的控制单元里面,有一个指令指针寄存器,他里面存放的是下一条指令在内存中的地址。控制单元会不停地将代码段指令拿进来,先放入指令寄存器。

    当前的指令分两部分:一部分是做什么操作,如加法还是位移,一部分是操作哪些数据。

    要执行这条指令,要把第一部分交个运算单元,第二部分交给数据单元。

    数据单元根据数据的地址,从数据段里面读到数据寄存器里,就可以进行运算了。运算单元昨晚运算,产生的结果会暂存在数据单元的数据寄存器里。最终,会有指令将数据写回到内存中的数据段。

    那么,怎样区分进程A和进程B呢?CPU里有两个寄存器,专门保持当前处理进程的代码段的起始地址,以及数据段的起始地址。这里面写的都是进程A,那当前执行的就是进程A的指令,等切换成了进程B,就会执行B的指令了,这个过程是进程切换。

    CPU和内存直接传数据,靠的是总线。

    当系统刚刚启动的时候,CPU 是处于实模式的,这个时候和原来的模式是兼容的。也就是说,哪怕你买了 32 位的 CPU,也支持在原来的模式下运行,只不过快了一点而已。

    当需要更多内存的时候,你可以遵循一定的规则,进行一系列的操作,然后切换到保护模式,就能够用到 32 位 CPU 更强大的能力。
    CPU 如何从启动开始,逐渐从实模式变为保护模式的?先按下不表,且听下回分说!

    15 | 调度(上):如何制定项目管理流程?

    在这里插入图片描述
    这一节我们讲了调度相关的数据结构,还是比较复杂的。一个 CPU 上有一个队列,CFS 的队列是一棵红黑树,树的每一个节点都是一个 sched_entity,每个 sched_entity 都属于一个 task_struct,task_struct 里面有指针指向这个进程属于哪个调度类。在调度的时候,依次调用调度类的函数,从 CPU 的队列中取出下一个进程。

    这样整个运行的场景就串起来了,在每个 CPU 上都有一个队列 rq,这个队列里面包含多个子队列,例如 rt_rq 和 cfs_rq,不同的队列有不同的实现方式,cfs_rq 就是用红黑树实现的。

    当有一天,某个 CPU 需要找下一个任务执行的时候,会按照优先级依次调用调度类,不同的调度类操作不同的队列。当然 rt_sched_class 先被调用,它会在 rt_rq 上找下一个任务,只有找不到的时候,才轮到 fair_sched_class 被调用,它会在 cfs_rq 上找下一个任务。这样保证了实时任务的优先级永远大于普通任务。

    16丨调度(中):主动调度是如何发生的?

    在这里插入图片描述
    一个运行中的进程主动调用 __schedule 让出 CPU。在 __schedule 里面会做两件事情,第一是选取下一个进程,第二是进行上下文切换。而上下文切换又分用户态进程空间的切换和内核态的切换。
    主动调度,就是进程运行到一半,因为等待 I/O 等操作而主动让出 CPU,然后就进入了我们的“进程调度第一定律”。所有进程的调用最终都会走 __schedule 函数。

    17 | 调度(下):抢占式调度是如何发生的?

    在这里插入图片描述
    整个进程的调度体系都放在里面。

    这个脑图里面第一条就是总结了进程调度第一定律的核心函数 __schedule 的执行过程,这是上一节讲的,因为要切换的东西比较多,需要你详细了解每一部分是如何切换的。

    第二条总结了标记为可抢占的场景,第三条是所有的抢占发生的时机,这里是真正验证了进程调度第一定律的。

    展开全文
  • 操作系统的发展历程 linux操作系统图解 Linux 操作系统爬坡路线图

    操作系统的发展历程

     

     

    linux操作系统图解

     

     

     

    Linux 操作系统爬坡路线图

     

     

     

    展开全文
  • 今天,菜鸟按照新的方法来,但是呢,由于问题比较大,所以我花了至少6个小时学习第二天没搞完的趣谈Linux操作系统,但是我突然发现,这些专栏的难度真的好大,我今天学了这么久,而且只搞这一个,感觉也只学会了60%...
  • 第一章 核心原理 Linux像外包公司?概述Linux 熟悉常用Linux命令 可能更新很慢!
  • 前言:学习的课程来自极客时间的专栏《趣谈 Linux 操作系统》,作者用形象化的比喻和丰富的图片让课程变得比较易懂,避免知识看过就忘,打算通过写学习笔记的形式记录自己的学习过程。 Linux 系统的相关介绍不再...
  • 1. Linux学习路径 2. Linux内核体系结构
  • 操作系统其实就像一个软件外包公司,其内核就相当于这家外包公司的老板。 鼠标和键盘是计算机的输入设备。大部分的普通用户想要告诉计算机应该做什么,都是通过这两个设备。例如,用户移动了一下鼠标,鼠标就会通过...
  • Linux 里,要创建一个新的进程,需要一个老的进程调用 fork 来实现,其中老的进程叫作父进程(Parent Process),新的进程叫作子进程(Child Process)。 当父进程调用 fork 创建进程的时候,子进程将各个子系统...
  • - 文件系统的功能 ... Windows→NTFS, Linux→ext3/ext4 fdisk -l 查看分区 mkfs.ext3/mkfs.ext4 /dev/… 进行格式化 可建立多个分区, 再分别以不同文件系统进行格式化 fdisk /dev/… 打开交互式程
  • 首先,我们知道操作系统是管理和控制计算机硬件与软件资源的计算机程序。这里把操作系统想象为一个软件外包公司,其内核就相当于这家外包公司的老板,那么我们可以把自己的角色切换成这家外包公司的老板,设身处地的...
  • 用于定位页 虚拟地址 = 虚拟页号 + 页内偏移 若采用单页表, 32位系统中一个页表将有 1M 页表项, 占用 4MB(每项 4B) Linux 32位系统采用两级页表: 页表目录(1K项, 10bit) + 页表(1K项, 10bit)(页大小(4KB, 12bit)) ...
  • 权限管理 x86 提供 4个 Ring 分层权限 操作系统利用: Ring0-内核态(访问核心资源); Ring3-用户态(普通程序) 用户态调用系统调用: 用户态-系统调用-保存寄存器-内核态执行系统调用-恢复寄存器-返回用户态 新进程执行...

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 193
精华内容 77
关键字:

趣谈linux操作系统

linux 订阅