2017-05-30 20:52:26 zhangxiao93 阅读数 7508

进程控制

每个进程都有一个非负整数表示的唯一进程ID
虽然唯一,不过可以复用,但不是立刻复用,而是使用延迟算法,防止将新进程误认为是使用同一ID的某个已经终止的先前进程.

特殊进程:

ID为0的是调度进程,该进程是内核的一部分,不执行任何磁盘上的程序
ID为1的是Init进程,init通常读取与系统有关的初始化文件(/etc/rc*文件、/etc/inittab文件、/etc/init.d/中的文件)
ID为2的是页守护进程,负责支持虚拟存储器系统的分页操作

除了进程ID,每个进程还有一些其他标识符:

#include <unistd.h>
pid_t getpid(void);//返回调用进程的进程ID
pid_t getppid(void);//调用进程的父进程ID
uid_t getuid(void);//调用进程的实际用户ID
uid_geteuid(void);//调用进程的有效用户ID
gid_t getgid(void);//调用进程的实际组ID
gid_t getegid(void);//调用进程的有效组ID

fork调用

#include <unistd.h>
pid_t fork(void);
//子进程返回0
//父进程返回子进程ID
//出错返回-1

fork函数被调用一次将返回两次,在子进程中返回0,在父进程中返回子进程的ID。
子进程获得父进程的数据空间、堆、栈副本

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <sys/time.h>
#include <malloc.h>

int globvar=6;//全局变量
char buf[]="hello world\r\n";
int main(void )
{
    int var;//栈上变量
    pid_t pid;
    var = 88;
    int *ptr=(int *)malloc(sizeof(int));
    *ptr=2;



    if(write(STDOUT_FILENO,buf,sizeof(buf)-1)!=sizeof(buf)-1)
    {
        printf("write error\r\n");
        return -1;
    }
    printf("before fork\r\n");

    if((pid=fork())<0)
    {
        printf("fork error");
        return -1;
    }
    else if(pid==0)//child 
    {
        ++*ptr;
        ++var;
        ++globvar;
    }
    else//parent
    {
        sleep(2);
    }

    printf("pid = %ld, globvar = %d, &var = %ld , var = %d , *ptr = %d , ptr=%ld\r\n",(long)getpid(),globvar,(long)&var, var ,*ptr,(long)ptr);
    free(ptr);
    return 0;
}

直接执行:

./fork

打印结果:

hello world
before fork
pid = 16722, globvar = 7, &var = 140722924809824 , var = 89 , *ptr = 3 , ptr=22728720
pid = 16721, globvar = 6, &var = 140722924809824 , var = 88 , *ptr = 2 , ptr=22728720

我们看到地址都是一样的,但是值不一样,说明子进程中发生了拷贝,但是为什么地址一样呢?

这里就涉及到物理地址和逻辑地址(或称虚拟地址)的概念。

操作系统讲逻辑地址转化成物理地址的过程叫做地址重定位。

分为:

静态重定位–在程序装入主存时已经完成了逻辑地址到物理地址和变换,在程序执行期间不会再发生改变。
动态重定位–程序执行期间完成,其实现依赖于硬件地址变换机构,如基址寄存器。

逻辑地址:

在计算机体系结构中是指应用程序角度看到的内存单元(memory cell)、存储单元(storage element)、网络主机(network host)的地址。
逻辑地址往往不同于物理地址(physical address),通过地址翻译器(address translator)或映射函数可以把逻辑地址转化为物理地址。

物理地址:

物理地址(英语:physical address),也叫实地址(real address)、二进制地址(binary address),
它是在地址总线上,以电子形式存在的,使得数据总线可以访问主存的某个特定存储单元的内存地址。
在和虚拟内存的计算机中,物理地址这个术语多用于区分虚拟地址。尤其是在使用内存管理单元(MMU)转换内存地址的计算机中,
虚拟和物理地址分别指在经MMU转换之前和之后的地址。

网上看到一篇很好的介绍物理地址、逻辑地址的博客:
http://www.cppblog.com/fwxjj/archive/2009/05/27/85897.html

了解了物理地址和逻辑地址,再看上述问题:

在fork之后exec之前两个进程用的是相同的物理空间(内存区),子进程的代码段、数据段、堆栈都是指向父进程的物理空间,也就是说,两者的虚拟空间不同,
但其对应的物理空间是同一个。

当父子进程中有更改相应段的行为发生时,再为子进程相应的段分配物理空间,
如果不是因为exec,内核会给子进程的数据段、堆栈段分配相应的物理空间(至此两者有各自的进程空间,互不影响),而代码段继续共享父进程的物理空间(两者的代码完全相同)。
而如果是因为exec,由于两者执行的代码不同,子进程的代码段也会分配单独的物理空间。

fork之后内核会通过将子进程放在队列的前面,以让子进程先执行,以免父进程执行导致写时复制,而后子进程执行exec系统调用,因无意义的复制而造成效率的下降。

fork时子进程获得父进程数据空间、堆和栈的复制,所以变量的地址(当然是虚拟地址)也是一样的。

每个进程都有自己的虚拟地址空间,不同进程的相同的虚拟地址显然可以对应不同的物理地址。因此地址相同(虚拟地址)而值不同没什么奇怪。

具体过程是这样的:
fork子进程完全复制父进程的栈空间,也复制了页表,但没有复制物理页面,所以这时虚拟地址相同,物理地址也相同,

但是会把父子共享的页面标记为“只读”类似mmap的private的方式),如果父子进程一直对这个页面是同一个页面

,直到其中任何一个进程要对共享的页面“写操作”,这时内核会复制一个物理页面给这个进程使用,同时修改页表。

而把原来的只读页面标记为“可写”,留给另外一个进程使用这就是所谓的“写时复制”

参考:http://www.cnblogs.com/zhangchaoyang/articles/2317420.html

上述代码如果执行:

./fork > see.txt

则打开see.txt文件,输出为:

hello world
before fork
pid = 14001, globvar = 7, &var = 140725591119472 , var = 89 , *ptr = 3 
before fork
pid = 14000, globvar = 6, &var = 140725591119472 , var = 88 , *ptr = 2 

多打印了一个before fork这是什么原因?

首先,stdin和stdout都是行缓冲,也就是遇到\n将flush缓冲区,因此在之前直接执行./fork时只打印一个before fork

因为缓冲区刷新了。

但是当重定向文件时,变成了标准输出变成全缓冲,因此,子进程就复制了缓冲区。

用一句话解释:

面向终端的缓冲时行缓冲,当并不指向交互式设备时,他们是全缓冲

因此,子进程复制了父进程的缓冲区

参考:http://blog.csdn.net/zhangxiao93/article/details/70666125

2018-06-16 18:56:29 TommyMusk 阅读数 6855

大纲:

理解Linux内核最好预备的知识点
Linux内核的特点
Linux内核的任务
内核的组成部分
哪些地方用到了内核机制?
Linux进程
Linux创建新进程的机制
Linux线程
内核线程
地址空间与特权级别
        虚拟地址与物理地址
        特权级别(Linux的两种状态)
        系统调用
设备驱动程序、块设备和字符设备
网络
文件系统

模块和热插拔

注:本文为《深入Linux内核架构》 的学习笔记


理解Linux内核最好预备的知识点:

  • 懂C语言
  • 懂一点操作系统的知识
  • 熟悉少量相关算法
  • 懂计算机体系结构


Linux内核的特点:

结合了unix操作系统的一些基础概念


Linux内核的任务:

1.从技术层面讲,内核是硬件与软件之间的一个中间层。作用是将应用层序的请求传递给硬件,并充当底层驱动程序,对系统中的各种设备和组件进行寻址。
2.从应用程序的层面讲,应用程序与硬件没有联系,只与内核有联系,内核是应用程序知道的层次中的最底层。在实际工作中内核抽象了相关细节。
3.内核是一个资源管理程序。负责将可用的共享资源(CPU时间、磁盘空间、网络连接等)分配得到各个系统进程。

4.内核就像一个库,提供了一组面向系统的命令。系统调用对于应用程序来说,就像调用普通函数一样。


内核实现策略:

1.微内核。最基本的功能由中央内核(微内核)实现。所有其他的功能都委托给一些独立进程,这些进程通过明确定义的通信接口与中心内核通信。

2.宏内核。内核的所有代码,包括子系统(如内存管理、文件管理、设备驱动程序)都打包到一个文件中。内核中的每一个函数都可以访问到内核中所有其他部分。目前支持模块的动态装卸(裁剪)。Linux内核就是基于这个策略实现的。


内核的组成部分:

1.用户空间(在“地址空间与特权级别”小节会详细介绍):
应用程序:
C库


2.内核空间(在“地址空间与特权级别”小节会详细介绍):
核心内核
设备驱动程序

硬件

详细可参考图1


图1 Linux内核组成部分


哪些地方用到了内核机制?

1.进程(在cpu的虚拟内存中分配地址空间,各个进程的地址空间完全独立;同时执行的进程数最多不超过cpu数目)之间进行通   信,需要使用特定的内核机制。
2.进程间切换(同时执行的进程数最多不超过cpu数目),也需要用到内核机制。
    进程切换也需要像FreeRTOS任务切换一样保存状态,并将进程置于闲置状态/恢复状态。

3.进程的调度。确认哪个进程运行多长的时间。


Linux进程

1.采用层次结构,每个进程都依赖于一个父进程。内核启动init程序作为第一个进程。该进程负责进一步的系统初始化操作。init进程是进程树的根,所有的进程都直接或者间接起源于该进程。
2.通过pstree命令查询。实际上得系统第一个进程是systemd,而不是init(这也是疑问点)

3.系统中每一个进程都有一个唯一标识符(ID),用户(或其他进程)可以使用ID来访问进程。

  • Linux创建新进程的机制;
        1.使用fork函数。
功能:创建当前进程的一个副本。父进程和子进程只有PID(进程ID)不同。父进程的内容被复制。(写时复制:可以了解下这个概念)


        2.使用exec函数。

功能:将一个新程序加载到当前进程的内存中并执行。旧程序的内存页将刷出,其内容替换为新的数据。然后开始执行新程序。


Linux线程

进程可以看成是一个正在执行的程序,而线程则是与主程序并行运行的程序函数或例程。

  • Linux创建新线程 

        采用clone方法创建线程。

  • 内核线程
        特点:
1.不与任何特定的用户空间进程相关联。
2.与中断上下文运转的内核相比,内核线程可以进入睡眠状态,也可以像系统中的普通进程一样被调度器跟踪。

用途:
1.从内存和块设备之间的数据同步。
2.帮助调度器在CPU上分配进程。

如何查看内核线程:
命令:ps fax   方括号内的就是内核线程。


地址空间与特权级别

在正式介绍之前先介绍几个单位:

KiB  2^10字节
MiB  2^20

GiB  2^30

  • 地址空间

    虚拟地址与物理地址:

        虚拟地址:在计算机的专用术语中是指标识一个虚拟(非物理地址)的实体地址。

        物理地址:切切实实存在的地址。在存储器里以字节为单位存储信息,为正确地存放或取得信息,每一个字节单元给以一个唯一的存储器地址,称为物理地址。

        映射关系:
            用页表为物理地址分配虚拟地址
    注意:未必虚拟地址的所有页都映射到某个页帧。
    原因:
1.页没有内存可以使用
2.数据尚不需要使用而没有载入内存。
3.页已经换出硬盘,需要时再换回内存。


    页帧:物理内存页
    页:专指虚拟地址空间中的页。
    页表:将虚拟地址空间映射到物理地址空间的数据结构。
    多级分页:建立虚拟地址到物理地址映射的一种方法,能有效减少内存用量。


    CPU加速内存的访问过程,方法:
    1.MMU(Memory Management Unit)内存管理单元
    2.TLB(Translation Lookaside Buffer)地址转换后备缓冲器

    IA-32位结构的CPU只需要使用二级页表,Linux内核总是使用四级页表,剩余部分由内核通过控页表对缺少的页表进行仿真。

    概念注意:

    1.CPU的字长决定了所能管理的地址空间的最大长度。对于32位系统是2^32 B = 4GiB
    2.虚拟地址空间:地址空间的最大长度与实际可用的物理内存的数量无关。
虚拟地址空间划分为两个部分:
内核空间

用户空间

                如图2所示:


图2 虚拟内存的划分

        有个等价名称值得一提:
用户层:指应用程序本身。指不属于内核的东西。
用户空间:不仅可以表示应用程序,还指代应用程序所运行的虚拟地址空间的一部分。与内核空间相对。

注意:每一个进程都有上述独立的虚拟地址空间。对于图2所示,每个进程有4GiB的内存空间。

  • 特权级别
        Linux有两种状态,两种状态代表两种特权级别:
       核心态:在虚拟地址的内核空间运行的状态。
       用户状态:在虚拟地址的用户空间运行的状态。
    注意:在用户状态禁止访问内核空间


        这两种状态的差别在于:对高于TASK_SIZE的内存区域的访问。

  • 系统调用
        定义:从用户状态到核心态的切换通过系统调用的特定手段完成。
方法:
1.内核代表用户程序执行代码
2.异步硬件中断激活,然后在中断上下文中进行。注意:在中断上下文运行时,内核不能进入睡眠状态。
        注意:

CPU大多数在执行用户空间中的代码。当应用程序执行系统调用时,则会切换到核心态,内核将完成其请求。在此期间,内核可以访问虚拟地址空间的用户部分。在系统调用完成之后,CPU切换回用户状态。 

        硬件中断也使CPU切换到核心态,但这种情况下内核不能访问用户空间。

        系统调用有哪些:

                进程管理
信号
文件
目录和文件系统
保护机制
定时器函数

如:在IA-32处理器上,Linux使用一个专用软件中断执行系统调用。

设备驱动程序、块设备和字符设备
设备驱动程序的任务:是在于支持应用程序经由设备文件与设备通信。换言之,使得能按恰当的方式在设备上读取/写入数据。
设备驱动程序的定义:用于与系统连接的输入/输出装置通信。如硬盘、软驱、各种接口、声卡等。


外设分为两类:
1.字符设备。提供连续的数据流,数据可以顺序读取,通常不支持随机存取。支持按字节/字符来读写数据。
典型:调制解调器
2.块设备。可以随机访问设备数据,程序可以自行确定读取数据的位置。不支持基于字符寻址,数据读写只能以块的倍数进行。
典型:硬盘。
复杂性:比字符设备复杂,因为设计到缓存机制。


网络
网卡也可以通过设备驱动程序控制。
但在内核中,网卡不能以设备文件访问。因为网络通信期间数据打包到各种协议层,内存处理数据必须针对协议层处理,才能有效将数据对接应用程序。
        为了支持用文件接口处理网络连接。Linux提供了套接字抽象,套接字可以看成是应用程序、文件接口、内核的网络实现之间的代理。


文件系统
文件存储在硬盘或者其他块设备(如光盘等),采用层次式文件系统。
文件系统使用目录结构主治存储的数据,并将其他原信息(如所有者、访问权限等)关联起来。


Linux支持许多不同的文件系统:
如标准的Ext2和Ext3文件系统、ReiserFS、XFS、VFAT等

注意:软件层(Virtual Filesystem虚拟文件系统)内核必须提供一个额外的软件层,将各种底层的文件系统的具体特征与应用层隔离开。如图3所示。


图3 文件系统的额外软件层

参考文献:

[1]Wolfgang Mauerer.《深入Linux内核架构》 Wolfgang Mauerer著 郭旭译 人民邮电出版社


2018-03-20 18:53:51 lafu5137 阅读数 5029

  • Linux内核:

        linux内核是一种开放源码的操作系统,由Linux Torvalds负责维护,提供硬件抽象层、硬盘及文件系统控制及多任务功能的系统核心程序。

  • Linux发行版:

        linux发行版基于linux内核源码,Linux系统的内核与外围实用程序(Utilities)软件和文档包装起来,并提供一些系统安装界面和系统配置、设定与管理工具,就构成了一种发行版本(distribution),Linux的发行版本其实就是Linux核心再加上外围的实用程序组成的一个大软件包。

linux主要发行版:

Fedora Core、Debian、Mandrake、Ubuntu、Red Hat Linux、SuSE、Linux Mint、Gentoo、CentOS、

2017-02-01 20:46:48 u010853261 阅读数 23813

我们经常需要通过类UNIX下连接我们的Linux服务器。比如我的Mac下经常需要连接上Linux服务器。一般系统都提供了ssh支持,可以直接连接:

通过命令:

ssh root@120.25.12.92

然后输入root用户的密码就行了。

如下图:
这里写图片描述

2018-05-27 12:16:53 cckevincyh 阅读数 22500

Linux简介

Linux是一种自由和开放源码的操作系统,存在着许多不同的Linux版本,但它们都使用了Linux内核。Linux可安装在各种计算机硬件设备中,比如手机、平板电脑、路由器、台式计算机
这里写图片描述

Linux介绍

Linux出现于1991年,是由芬兰赫尔辛基大学学生Linus Torvalds和后来加入的众多爱好者共同开发完成

Linux特点

多用户,多任务,丰富的网络功能,可靠的系统安全,良好的可移植性,具有标准兼容性,良好的用户界面,出色的速度性能
开源

CentOS

  • 主流:目前的Linux操作系统主要应用于生产环境,主流企业级Linux系统仍旧是RedHat或者CentOS
  • 免费:RedHat 和CentOS差别不大,基于Red Hat Linux 提供的可自由使用源代码的企业CentOS是一个级Linux发行版本
  • 更新方便:CentOS独有的yum命令支持在线升级,可以即时更新系统,不像RedHat 那样需要花钱购买支持服务!

Linux目录结构

这里写图片描述

  • bin (binaries)存放二进制可执行文件
  • sbin (super user binaries)存放二进制可执行文件,只有root才能访问
  • etc (etcetera)存放系统配置文件
  • usr (unix shared resources)用于存放共享的系统资源
  • home 存放用户文件的根目录
  • root 超级用户目录
  • dev (devices)用于存放设备文件
  • lib (library)存放跟文件系统中的程序运行所需要的共享库及内核模块
  • mnt (mount)系统管理员安装临时文件系统的安装点
  • boot 存放用于系统引导时使用的各种文件
  • tmp (temporary)用于存放各种临时文件
  • var (variable)用于存放运行时需要改变数据的文件

Linux常用命令

命令格式:命令 -选项 参数

如:ls  -la  /usr

ls:显示文件和目录列表(list)

常用参数:

-l      (long)
-a  (all)         注意隐藏文件、特殊目录.和..   
-t      (time)

Linux命令的分类

内部命令:属于Shell解析器的一部分

cd 切换目录(change directory)
pwd 显示当前工作目录(print working directory)
help 帮助

外部命令:独立于Shell解析器之外的文件程序

ls 显示文件和目录列表(list)
mkdir 创建目录(make directoriy)
cp 复制文件或目录(copy

查看帮助文档

内部命令:help + 命令(help cd)
外部命令:man + 命令(man ls)

操作文件或目录常用命令

pwd 显示当前工作目录(print working directory)
touch 创建空文件                                 
mkdir 创建目录(make directoriy)
-p 父目录不存在情况下先生成父目录 (parents)            
cp 复制文件或目录(copy)
-r 递归处理,将指定目录下的文件与子目录一并拷贝(recursive)     
mv 移动文件或目录、文件或目录改名(move)

rm 删除文件(remove)
-r 同时删除该目录下的所有文件(recursive)
-f 强制删除文件或目录(force)
rmdir 删除空目录(remove directoriy)
cat显示文本文件内容 (catenate)
more、less 分页显示文本文件内容
head、tail查看文本中开头或结尾部分的内容
haed  -n  5  a.log 查看a.log文件的前5行
tail  -F b.log 循环读取(follow)

常用命令

wc 统计文本的行数、字数、字符数(word count)
-m 统计文本字符数
-w 统计文本字数
-l 统计文本行数
find 在文件系统中查找指定的文件
find /etc/ -name "aaa"
grep 在指定的文本文件中查找指定的字符串
ln 建立链接文件(link)
-s 对源文件建立符号连接,而非硬连接(symbolic)

top 显示当前系统中耗费资源最多的进程 
ps 显示瞬间的进程状态
-e /-A 显示所有进程,环境变量
-f 全格式
-a 显示所有用户的所有进程(包括其它用户)
-u 按用户名和启动时间的顺序来显示进程
-x 显示无控制终端的进程
kill 杀死一个进程
kill -9 pid
df 显示文件系统磁盘空间的使用情况

du 显示指定的文件(目录)已使用的磁盘空间的总
-h文件大小以KMG为单位显示(human-readable)
-s只显示各档案大小的总合(summarize)
free 显示当前内存和交换空间的使用情况 
netstat 显示网络状态信息
-a 显示所有连接和监听端口
-t (tcp)仅显示tcp相关选项
-u (udp)仅显示udp相关选项
-n 拒绝显示别名,能显示数字的全部转化成数字。
-p 显示建立相关链接的程序名
ifconfig 网卡网络配置详解 
ping 测试网络的连通性 

备份压缩命令

gzip 压缩(解压)文件或目录,压缩文件后缀为gz 
bzip2 压缩(解压)文件或目录,压缩文件后缀为bz2 
tar 文件、目录打(解)包

gzip命令

命令格式:gzip [选项] 压缩(解压缩)的文件名
-d将压缩文件解压(decompress)
-l显示压缩文件的大小,未压缩文件的大小,压缩比(list)
-v显示文件名和压缩比(verbose)
-num用指定的数字num调整压缩的速度,-1或--fast表示最快压缩方法(低压缩比),-9或--best表示最慢压缩方法(高压缩比)。系统缺省值为6

bzip2命令

命令格式:bzip2 [-cdz] 文档名
-c将压缩的过程产生的数据输出到屏幕上
-d解压缩的参数(decompress)
-z压缩的参数(compress)
-num 用指定的数字num调整压缩的速度,-1或--fast表示最快压缩方法(低压缩比),-9或--best表示最慢压缩方法(高压缩比)。系统缺省值为6

tar命令

-c 建立一个压缩文件的参数指令(create)
-x 解开一个压缩文件的参数指令(extract)
-z 是否需要用 gzip 压缩
-j 是否需要用 bzip2 压缩
-v 压缩的过程中显示文件(verbose)
-f 使用档名,在 f 之后要立即接档名(file)

关机/重启命令

shutdown系统关机 
-r 关机后立即重启
-h 关机后不重新启动
halt 关机后关闭电源 shutdown -h
reboot 重新启动 shutdown -r

学习Linux的好习惯

  • 善于查看man page(manual)等帮助文档
  • 利用好Tab键
  • 掌握好一些快捷键

    ctrl + c(停止当前进程)
    ctrl + r(查看命令历史)
    ctrl + l(清屏,与clear命令作用相同)
    

Linux需要学什么

阅读数 1324

Linux 关闭桌面方法

阅读数 2637

Linux关闭桌面方法

博文 来自: guichenglin

LINUX安装ODBC驱动

阅读数 11120

LINUX安装ODBC驱动

博文 来自: dongweizu33
没有更多推荐了,返回首页