吴江区经济开发区建设工程网站,网站 宕机 优化,form e哪个网站做,网站建设服务费会计分录Linux启动过程
1、主机加电自检#xff0c;加载BIOS硬件信息
2、读取MBR引导文件
3、引导linux内核
4、启动第一个进程init#xff08;进程号永远为1#xff09;
5、进度相应的运行级别
6、运行终端#xff0c;输入用户名和密码
linux系统缺省的运行级别
关机、单机…Linux启动过程
1、主机加电自检加载BIOS硬件信息
2、读取MBR引导文件
3、引导linux内核
4、启动第一个进程init进程号永远为1
5、进度相应的运行级别
6、运行终端输入用户名和密码
linux系统缺省的运行级别
关机、单机用户模式、字符界面的多用户模式不支持网络、字符界面的多用户模式、未分配使用、图形界面的多用户模式、重启
fork函数说明
失败返回-1
fork方法被调用一次成功就会有两次返回
在父进程中返回一次返回的是子进程的pid非0
在子进程中返回一次返回值为0
fork被调用后的linux内核动作
1、分配新的内存块和内核数据结构给子进程
2、将父进程部分数据结构内容拷贝到子进程
3、将子进程添加到系统进程调度表
4、fork返回开始调度器调度
fork后子进程是否可以共享父进程打开的文件
fork之后父子进程会共享文件的描述符主要是对文件读写偏移量的共享。
linux进程间通信方式
1、管道pipe、流管道s_pipe、有名管道(FIFO)
常说的管道多为匿名管道匿名管道只能用于具有亲缘关系的进程之间这是和有名管道之间最大的区别有名管道可以用mkfifo()创建匿名管道用pipe()创建
#includestdio.h#includeunistd.hint main(){int n, fd[2]; // 这里的fd是文件描述符的数组用于创建管道做准备的pid_t pid;char line[100];if (pipe(fd) 0) // 创建管道printf(pipe create error/n);if ((pid fork()) 0) //利用fork()创建新进程printf(fork error/n);else if (pid 0) { //这里是父进程先关闭管道的读出端然后在管道的写端写入“hello worldclose(fd[0]);write(fd[1], hello word/n, 11);}else {close(fd[1]); //这里是子进程先关闭管道的写入端然后在管道的读出端读出数据n read(fd[0], line, 100);write(STDOUT_FILENO, line, n);}exit(0);}
2、信号
信号的处理方式
忽略此信号SIGKILL和SIGSTOP除外原因他们向内核和超级用户提供了使进程终止或停止的可靠方法
捕捉信号通知内核在某种信号发生时调用一个用户函数
执行默认动作
3、消息队列
消息队列本身是异步操作消息队列的发送/接收者不需要同时与消息队列交互消息保存在对列中直到接收者取回处理。
消息队列的标识符是消息队列在内核系统的身份信息是唯一的。
消息队列的限制
1、消息队列个数最多为16个
2、消息队列总容量最多为1024*1616384字节
3、每个消息队列的内容最大为1024*88192字节
System V提供的IPC通信机制需要一个key值通过key 值就可在系统内获得一个唯一的消息队列。
key值可以是人为指定的也可以通过ftok函数获得。 1.创建消息队列 int msgget(key_t key, int msgflg); msgflg: 标识函数的行为及消息队列的权限其取值如下 IPC_CREAT创建消息队列。 IPC_EXCL 检测消息队列是否存在。 位或权限位消息队列位或权限位后可以设置消息队列的访问权限但可执行权限未使用。一般是0666 返回值 成功返回消息队列的标识符 失败返回 2.写入消息 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); msgflg函数的控制属性其取值如下 0: msgsnd()调用阻塞直到条件满足为止。 IPC_NOWAIT: 若消息没有立即发送则调用该函数的进程会立即返回。 返回值成功返回0失败返回-1。 3.读取消息 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg); msgtyp消息的类型 msgtyp 0返回队列中的第一个消息。 msgtyp 0返回队列中消息类型为 msgtyp 的消息常用。 msgtyp 0返回队列中消息类型值小于或等于 msgtyp 绝对值的消息如果这种消息有若干个则取类型值最小的消息。在获取某类型消息的时候若队列中有多条 此类型的消息则获取最先添加的消息即先进先出原则。 msgflg函数的控制属性 0: msgrcv() 调用阻塞直到接收消息成功为止。 MSG_NOERROR: 若返回的消息字节数比 nbytes 字节数多,则消息就会截短到 nbytes 字节且不通知消息发送进程。 IPC_NOWAIT: 调用进程会立即返回。若没有收到消息则立即返回 -1。 返回值 成功读取消息的长度 失败-1 4.消息队列控制 int msgctl(int msqid, int cmd, struct msqid_ds *buf); cmd IPC_RMID 删除消息队列。从系统中删除给消息队列以及仍在该队列上的所有数据这种删除立即生效。仍在使用这一消息\ 队列的其他进程在它们下一次试图对此队列进行操作时将出错并返回EIDRM。 此命令只能由如下两种进程执行 1.其有效用户ID等于msg_perm.cuid或msg_perm.guid的进程。 2.另一种是具有超级用户特权的进程。 IPC_SET 设置消息队列的属性。按照buf指向的结构中的值来设置此队列的msqid_id结构。该命令的执行特权与上一个相同。 IPC_STAT读取消息队列的属性。取得此队列的msqid_ds结构并存放在buf*中。 IPC_INFO读取消息队列基本情况。 buf队列中的内容一般为NULL。
4、共享内存
共享内存不同于内存映射区它不属于任何进程且不受进程生命周期的影响。通过调用linux的系统函数获得该块共享内存使用之前需要将共享内存和进程进行关联得到共享内存的起始地址就可以进行
读写操作。进程也可以和该块共享内存取消关联取消关联后就不能操作该块内存了。在所有的进程间通信方式中共享内存是效率最高的。
共享内存默认是不阻塞的如果多个进程同时读写共享内存可以出现数据错乱共享内存需要借助其他机制来保证进程间的数据同步比如信号量
共享内存使用步骤
调用shmget创建一个新的共享内存段或者获取一个既有的共享内存段的标识符。
使用shmat来附上共享内存段即使该段成为调用进程的虚拟内存的一部分调用后返回addr值即指向共享内存起始地址的指针
调用shmdt来分离共享内存段调用后该进程就无法再引用该段共享内存
调用shmctl来删除共享内存段只有当当前所有附件内存段的进程都与之分离后内存段才会销毁只有一个进程需要执行这一步。
共享内存和内存映射的区别
1、共享内存可以直接创建内存映射需要磁盘文件(匿名映射除外)
2、共享内存效果更高
3、内存
1、所有的进程操作的是同一块共享内存。
2、内存映射,每个进程在自己的虚拟地址空间中有一个独立的内存。
4、数据安全
1、进程突然退出
共享内存还存在
内存映射区消失
2、运行进程的电脑死机宕机了
数据存储在共享内存中,没有了
内存映射区的数据,由于磁盘文件中的数据还在所以内存映射区的数据还存在
5、生命周期
共享内存进程退出,共享内存还在标记删除(所有的关联的进程数为0)或者关机、如果一个进程退出会自动和共享内存进行取消关联。
内存映射区 进程退出内存映射区销毁
5、信号量
信号量是用于不同进程或者不同线程之间同步手段的原语分为
1、Posix有名信号量可用于进程或线程间的同步
sem_open创建或者打开一个信号量
name信号量在文件系统上的文件名
oflag可以为0,O_CREAT或者O_CREAT|O_EXCL
mode信号量的权限位
value信号量的初值不能大于SEM_VALUE_MAX
返回自sem_t是一个该信号量的标识符的指针
sem_close关闭一个信号量但是并不删除信号量另外进程终止系统会自动关闭当前进程打开的信号量
sem信号量的指针通过sem_open获得
sem_unlink删除信号量需要注意的是信号量同样维护了一个引用计数只有当引用计数为0时才会显示的删除
name信号量的在文件系统上的唯一标示
sem_postV操作将信号量的值1并唤醒等待信号量的任意线程
sem信号量的指针通过sem_open获得
sem_waitP操作如果当前信号量小于等于0则阻塞将信号量的值-1否则直接将信号量-1
sem信号量的指针通过sem_open获得
sem_trywait非阻塞的sem_wait
sem信号量的指针通过sem_open获得
sem_getvalue获取当前信号量的值如果当前信号量上锁则返回0或者负值其绝对值为信号量的值
sem信号量的指针通过sem_open获得
sval信号量的值
以上的函数除了sem_open失败返回SEM_FAILED均是成功返回0失败返回-1并且设置errno。
2、Posix基于内存的信号量无名信号量存放于共享内存中可用于进程或者线程同步
sem_init初始化一个无名信号量
sem信号量的指针
pshared标志是否共享
pshared0该信号量只能在同一进程不同线程之间共享当进程终止则消失
pshared!0该信号量驻留与共享内存区可以在不同进程之间进行共享
value信号量的初值
返回值出错返回-1成功并不返回0
sem_destroy销毁信号量。成功返回0失败返回-1。
3、System V信号量在内核中维护可用于进程或线程间同步
6、套接字
套接字类型
流式套接字即TCP套接字用SOCK_STREAM表示
数据报套接字即UDP套接字或称无连接套接字用SOCK_DGRAM表示
原始套接字用SOCK_RAM表示
套接字地址结构由网络地址和端口号组成
int Socket_fd socket(AF_INET, SOCK_DGRAM, 0);//指定协议族AF_INET/PF_INET,SOCK_DGRAM/SOCK_STREAM使用数据包传输还是字节流传输
struct sockaddr_in address;//IPv4的地址结构体之后给地址结构体赋值
address.sin_family AF_INET;//指定使用的地址族
address.sin_port htons(port);//指定感兴趣的端口号并要转换成网络字节序
inet_pton(AF_INET, ip, address.sin_addr);//将ip地址转换成网络字节序赋值给sin_addr
int ret bind(Socket_fd, (struct sockaddr*)address, sizeof(address));//将ip地址和感兴趣的port关联到创建的udp文件描述符
ret listen(Socket_fd, backlog);//监听是否有连接backlog为连接的最大数
//这里的recvfrom()和sendto是Udp传输专用的API函数。
recvfrom(Socket_fd, buf, sizeof(buf), 0, (struct sockaddr*)send_addr, addrlen);//将接收到数据存放在buf中 并将对方的ip地址和port端口号存储在send_addr结构体中。
sendto(Socket_fd, buf, sizeof(buf), 0, (struct sockaddr*)send_addr, addrlen);//将数据buf发送给地址和端口号为send_addr的机器上。
//TCP数据读写函数
ssize_t recv(socketfd, buf, sizeof(buf), 0);
ssize_t send(socketfd, buf, sizeof(buf), 0);
//接收连接与发起连接函数
int accept(socketfd, struct sockaddr* addr, socklen_t *addrlen);//接收连接保存的是对方的ip和port
int connect(socketfd, const struct sockaddr* addr, socklen_t *addrlen);//服务器的ip和端口号
Linux交换空间swap space
交换空间是linux使用的一定空间可以是一个分区也可以是一个文件或者文件和分区的组合用于临时保存一些并发运行程序当RAM没有足够的内存来容纳正在执行的所有程序时
就会发生这种情况。linux物理内存吃紧时将内存中不常访问的数据保存到swap上这样系统就有更多的物理内存为各个进程服务。
swap space好处
1、系统就可以将这部分不这么使用的内存数据保存到 swap 上去从而释放出更多的物理内存供系统使用。
2、很多发行版本的休眠功能依赖于swap分区当系统休眠的时候会将内存中的数据保存到swap上等下次启动时再将数据加载到内存中这样可以加速系统启动所以使用休眠功能必须配置swap分区
并且大小一定要大于物理内存
3、在某些情况下物理内存是有限的但是为了能达到运行耗内存程序的目的就通过配置足够的swap空间来达到目的虽然慢一些但是可以达到运行的目的
4、虽然大部分情况下物理内存都是够用的但是总有一些意想不到的状况比如某个进程需要的内存超过了预期或者有进程存在内存泄漏等当内存不够的时候就会触发内核的 OOM killer
根据 OOM killer 的配置某些进程会被 kill 掉或者系统直接重启(默认情况是优先 kill 耗内存最多的那个进程)不过有了 swap 后可以拿 swap 当内存用虽然速度慢了点但至少给了我
们一个去 debug、kill 进程或者保存当前工作进度的机会。
5、如果能将不怎么常用的内存数据移动到 swap 上就会有更多的物理内存用于 cache从而提高系统整体性能。
交换空间配置
1、创建swap文件#dd if/dev/zero of/swap1 bs1M count1024
dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换。
if文件名输入文件名缺省为标准输入。即指定源文件
of文件名输出文件名缺省为标准输入。即指目的文件。
bs1M设置输入/输出的块的大小
count1024指拷贝1024个块即1G。
2、将上一步新建的文件设置为swap分区文件#mkswap /swap1
3、激活swap启用分区文件#swapon /swap1
4、在/etc/fstab文件中添加下面的内容/swap1 swap swap defaults 0 0
5、 通过free查看交换空间大小看是否修改成功
LILO
LILO是linux的引导加载程序主要用于将linux操作系统加载到主内存中以便它可以开始运行
Linux配置lilo方法修改/etc/lilo.conf文件然后运行lilo命令。
inode
每个文件的属性信息比如大小时间类型等成为文件的元数据metadata这些数据都存在inode(index node)表中innode表中是由很多记录组成的一条记录对应的存放的
一个文件的元数据信息
每一个inode表记录对应的保存了以下的信息
inode number 节点号
文件类型
UID
GID
链接数指向这个文件名路径名称个数
该文件的大小和不同的时间戳
有关文件的其他数据
#dumpe2fs /dev/sdc1
Inode count: 65536 inode号数量
Block count: 262144 块数量
Reserved block count: 13107 保留块数量
Block size: 4096 块大小 4K
Reserved blocks uid: 0 (user root) 保留下来的块分配给root用户与root组
Reserved blocks gid: 0 (group root)
superblock 超级块存放元数据信息
Backup superblock 备份超级块
Group 0: (Blocks 0-32767) [ITABLE_ZEROED] 组0
mkfs.ext4 --help
[-i bytes-per-inode] 默认16K
[-N number-of-inodes]
[-I inode-size]
[-J journal-options]
[-G flex-group-size]
[-N number-of-inodes]
软链接和硬链接
硬链接可以理解为一个指针指向文件索引节点的指针系统不另外给分配inode每添加一个硬链接文件链接数加1。
不足
1、不可以在不同文件系统的文件间建立连接2、只有超级用户才可以为目录创建硬链接
软链接软连接克服了硬链接的不足没有文件系统的限制使用更广泛甚至可以跨越不同机器不同网络对文件进行链接。
不足
因为链接文件包含有原文件的路径信息所以当原文件从一个目录下移动到其他目录中再访问链接文件系统就找不到了而硬链接没这个缺陷。
实际使用场景下基本使用软链接。
总结
1、硬链接不可以跨区软链接可以
2、硬链接指向一个inode的节点软链接创建一个新的inode
3、删除硬链接文件不会删除原文件删除软链接文件会把原文件删除
CC攻击和DDOS攻击
CC攻击主要用来攻击页面的模拟多个用户不停的对页面进行访问从而使系统资源耗尽
DDOS攻击分布式拒绝服务攻击借助服务器技术将多个计算机联合起来攻击平台来对一个或多个目标发动DDOS攻击
防止攻击通过硬件防火墙做流量清洗将攻击流量引入黑洞。
Linux性能调优
1、Disabling daemons(关闭daemons)
2、shutting down the GUI(关闭GUI)
3、changing kernel params(改变内核参数)
4、内核参数
5、处理器子系统调优
6、内存子系统调优
7、文件系统子系统调优
8、网络系统子系统调优
Linux内核锁
自旋锁和信号量
自旋锁
最多被一个可执行线程持有如果一个执行线程试图请求一个已被占用的自旋锁那么这个线程就会一直进行忙循环-旋转-等待锁重新可用。要是锁未被征用请求它的执行线程便能立刻得到它并
继续进行。自旋锁可以在任何时刻防止多余一个的执行线程同时进入临界区。
信号量
linux的信号量是一种睡眠锁如果有一个任务试图获取一个已被持有的信号量时信号量会将其推入等待队列然后让其睡眠。
Linux怎么申请大块内存
随着系统运行时间的增加申请大块内存的机会逐渐减少所以一般建议在系统启动阶段申请大块内存但是其成功的几率只是比后续申请要高而已不是100%。如果程序很在意申请成功与否就
只能退用“启动内存Boot Memory”。
通过伙伴系统申请内核内存的函数有哪些
在物理页面管理上实现了基于区的伙伴系统zone based buddy system对不同区的内存使用单独的伙伴系统buddy system管理而且独立监控空闲页。相应接口alloc_pages(gfp_mask, order),
__get_free_pages(gfp_mask,order)等。
Linux虚拟文件系统的关键数据结构
struct super_block 超级块代表了整个文件系统超级块是文件系统的控制块有整个文件系统信息一个文件系统所有的inode都要连接到超级块上可以说一个超级块就代表了一个文件系统。
struct inode 索引节点对象由inode结构体表示定义文件在linux/fs.h中
struct file 定义在include/linux/fs.h中定义文件结构体代表一个打开的文件系统中的每个打开的文件在内核空间都有一个关联的 struct file。
struct dentry 目录项是描述文件的逻辑属性。文件系统中某个索引(inode)的链接。这个索引节点可以是文件也可以是目录
Linux中的文件包括哪些
执行文件、普通文件、目录文件、链接文件、设备文件、管道文件
创建一个进程的系统调用
clone\fork\vfork\
使用schedule()进行进程切换的方式
1、系统调用do_fork()
2、定时中断do_timer()
3、唤醒进程wake_up_process()
4、改变进程的调度策略setscheduler()
5、系统调用礼让sys_sched_yield()
进程调度的核心数据结构
strcut runqueue实时运行队列结构
加载和卸载一个模块
insmod加载、rmmod卸载
模块和应用程序分别运行的空间
模块运行在内核空间应用程序运行在用户空间
Linux 中的浮点运算由应用程序实现还是内核实现
应用程序实现,Linux 中的浮点运算是利用数学库函数实现的,库函数能够被应用程序链接后调用,不能被内核链接调用。这些运算是在应用程序中运行的,然后再把结果反馈给系统。 Linux 内核如果
一定要进行浮点运算,需要在建立内核时选上 math-emu,使用软件模拟计算 浮点运算,据说这样做的代价有两个:用户在安装驱动时需要重建内核,可能会影响到其他的应用程序,使得这些应用程序在做
浮点运算的时候也使用 math-emu,大大的降低了效率。
TLB中缓存的内容
TLB 页表缓存当线性地址被第一次转换成物理地址的时候将线性地址和物理地址的对应放到TLB中用于下次访问这个线性地址时加快转换速度。
设备驱动程序函数
open\read\write\llseek\release
Linux系统调用的方法
靠软件中断实现的首先用户程序为系统调用设置参数其中一个编号是系统调用编号参数设置完成后程序执行系统调用指令X86上软中断是有int产生的这个指令会导致一个异常产生于一个
事件这个事情会导致处理器跳到内核态并跳转到一个新地址。并开始处理那里的异常处理程序此时的异常处理就是系统调用程序
Linux软中断和工作队列的作用
Linux中的软中断和工作队列是中断处理。
1、软中断一般是“可延迟函数”的总成它不能睡眠不能阻塞处于中断上下文不能进程切换软中断不能被自己打断只能被硬件中断打断可以并发的运行在多个CPU上。
所以软中断必须设计成可重入的函数,因此也需要自旋锁来保护其数据结构。
2、工作队列中的函数处在进程上下文中,它可以睡眠,也能被阻塞,能够在不同的进程间切换。已完成不同的工作。可延迟函数和工作队列都不能访问用户的进程空间,可延时函数在执行时不可能有任何正在
运行的进程,工作队列的函数有内核进程执行,他不能访问用户空间地址。
Linux线程优先级设置
SCHED_FIFO:先进先出调度在先进先出调度方式下一个线程直到它被更高优先级的线程抢占或者运行结束才会交出控制权。相同优先级的任务不能打断该线程。当线程完成后内核会寻找处于就绪状态相同
优先级的线程如果不存在则寻找低优先级线程。FIFO调度本身实现了数据的互斥在线程运行时间内其他相同优先级线程无法进行资源抢占。
SCHED_RR时间片轮转调度在时间片轮转调度下一个线程放弃内核有三种情况运行结束被更高优先级抢占或消耗完自己的时间片。时间片是线程运行的最小时间单元由操作系统预先设定。
当时间片用完时该线程交出控制权之后内核会按照和FIFO相同的方式搜索下一个工作线程。轮转调度可以防止某一个任务连续占用太多的资源而导致其他线程信息得不到及时处理。缺点是轮转调度
会增加由于任务切换而导致的开销。
SCHED_OTHER分时调度一般采用CFS算法CFS算法定义了一个新的调度模型它给cfs_rq(run queue)中的每一个进程都设置一个虚拟时钟。如果一个进程得以执行随着执行时间的不断增加其
虚拟时钟-virtual runtime(vruntime)也将不断增加没有得到执行的进程虚拟时钟将保持不变。
而调度器将会选择最小的vruntime那个进程来执行。这就是所谓的“完全公平”。不同优先级的进程其vruntime增长速度不同优先级高的进程vruntime增长得慢所以它可能得到更多的运行机会。
优先级设置和获取优先级函数
pthread_attr_setschedparam、pthread_attr_getschedparam
系统创建线程时默认的线程是SCHED_OTHER。所以如果我们要改变线程的调度策略的话可以通过pthread_attr_setschedpolicy实现
Linux下优先级翻转
优先级翻转
当一个高优先级线程通过信号量机制访问共享资源时该信号量已被一个低优先级线程占用而这个低优先级的任务在访问共享资源时可能又被一个中等优先级任务抢占。从以上描述高优先级被许多
较低优先级的任务阻塞导致高优先级的实时性得不到保证。
解决方案
1、设置优先级上限给临界区一个高优先级进入临界区的进程都将获得这个高优先级如果其他试图进入临界区的进程的优先级都低于这个高优先级那么优先级反转就不会发生。
2、优先级继承当一个高优先级进程等待一个低优先级进程持有的资源时低优先级进程将暂时获得高优先级进程的优先级在释放资源后低优先级进程回到原来的优先级。嵌入式系统VxWorks就是采用
这个策略。
Linux线程礼让
让当前正在执行的线程暂停但不阻塞将线程从运行状态转为就绪状态让CPU重新调度礼让不一定成功看CPU当前情况。
A和B两个线程当CPU执行B的时候B进行礼让那么就离开CPU这个时候B就变为就绪状态CPU就重新在A线程和B线程之间进行选择有可能还是让B线程执行这个时候就没礼让成功。