Linux学习笔记一Word文件下载.docx
《Linux学习笔记一Word文件下载.docx》由会员分享,可在线阅读,更多相关《Linux学习笔记一Word文件下载.docx(13页珍藏版)》请在冰豆网上搜索。
随内核的持续性;
管道
管道:
intpipe(intfiledes[2])
使用环境:
父子进程间通信,单向的、半双工
使用原则:
(1)创建两个文件描述符,fd[0]是读管道、fd[1]是写管道;
(2)一个进程调用pipe然后调用fock产生一个子进程,子进程继承父进程的资源,这样就建立了IPC通道;
(3)读数据的进程关闭管道写入端,写数据的进程关闭管道的读出端;
FIFO(命名管道)
FIFO:
Intmkfifo(constchar*pathname,mode_tmode)
可以在无关联进程间通信,单向的、半双工
先进先出FIFO;
打开函数操作;
非阻塞:
调用open函数时可以指定O_NONBLOCK标志
如果一个描述符已经打开,可以调用fcntl以启用O_NONBLOCK标志
管道与FIFO:
当一个管道或FIFO的最后一次关闭发生时,仍在管道或FIFO上的数据将被丢弃;
这与消息队列不同;
3:
信号
以SIG开头:
SIGHUP:
SIGINT
SIGKILL
SIGSTOP
处理方式:
忽略方式:
SIGKILL和SIGSTOP不能忽略
执行用户希望操作
执行默认操作
信号发送:
kill和raise函数
Kill即可以向本身进程发送信号,也可以向其他进程发送信号;
Intkill(pid_tpai,intsigno)
Raise只能向进程本身发送信号;
Intraise(intsigno)
alarm函数可以发送信号
pause函数时调用进程挂起直至捕捉到一个信号;
信号处理:
利用信号函数
2:
使用信号集函数组
4:
内存共享
共享内存是被多个进程共享的一部分物理内存。
共享内存是进程间共享数据的一种最快方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容;
实现步骤:
创建共享内存,使用shmget函数;
映射共享内存,将这段创建的共享内存映射到具体的进程空间去,使用shmat函数;
当一个进程不再需要共享内存时,需要把它从进程地址空间中脱离。
Intshmdt(char*shmaddr)
5:
消息队列
消息队列可认为是一个消息的链表;
消息队列是随内核持续的,只有内核重启或人为删除才消失;
Posix消息队列:
Mq_open、mq_close、mq_unlink
mq_send、mq_receive
SystemV:
打开/创建:
Intmsgget(key_tkey,intmsgflg)
发送消息:
向消息队列发送一条消息
Intmsgsnd(intmsqid,structmsgbuf*msgp,intmsgsz,intmsgflg)
接收消息:
Intmsgrct(intmsqid,structmsgbuf*msgp,intmsgsz,longmsgtyp,intmsgflg)
6:
信号量
信号量是一种用于提供不同进程间或一个给定进程的不同线程间同步手段的原语;
Posix有名信号量:
可用于进程或线程间的同步
Posix基于内存的信号量:
存放在共享内存区中,可用于进程或线程间同步;
SystemV信号量:
在内核中维护,可用于进程或线程间同步;
主要用途是保护临界资源。
Intsemget(key_tkey,intnsems,intsemflg)
操作:
Intsemop(intsemid,structsembuf*sops,unsignednsops)
参数:
semid:
信号集的识别码,可通过semget获取。
sops:
指向存储信号操作结构的数组指针,信号操作结构的原型如下
structsembuf
{
unsignedshortsem_num;
/*semaphorenumber*/
shortsem_op;
/*semaphoreoperation*/
shortsem_flg;
/*operationflags*/
};
这三个字段的意义分别为:
sem_num:
操作信号在信号集中的编号,第一个信号的编号是0。
sem_op:
如果其值为正数,该值会加到现有的信号内含值中。
通常用于释放所控资源的使用权;
如果sem_op的值为负数,而其绝对值又大于信号的现值,操作将会阻塞,直到信号值大于或等于sem_op的绝对值。
通常用于获取资源的使用权;
如果sem_op的值为0,则操作将暂时阻塞,直到信号的值变为0。
sem_flg:
信号操作标志,可能的选择有两种
IPC_NOWAIT//对信号的操作不能满足时,semop()不会阻塞,并立即返回,同时设定错误信息。
IPC_UNDO//程序结束时(不论正常或不正常),保证信号值会被重设为semop()调用前的值。
这样做的目的在于避免程序在异常情况下结束时未将锁定的资源解锁,造成该资源永远锁定。
nsops:
信号操作结构的数量,恒大于或等于1。
timeout:
当semtimedop()调用致使进程进入睡眠时,睡眠时间不能超过本参数指定的值。
如果睡眠超时,semtimedop()将失败返回,并设定错误值为EAGAIN。
如果本参数的值为NULL,semtimedop()将永远睡眠等待。
返回说明:
成功执行时,两个系统调用都返回0。
失败返回-1,errno被设为以下的某个值
E2BIG:
一次对信号的操作数超出系统的限制
EACCES:
调用进程没有权能执行请求的操作,并且不具有CAP_IPC_OWNER权能
EAGAIN:
信号操作暂时不能满足,需要重试
EFAULT:
sops或timeout指针指向的空间不可访问
EFBIG:
sem_num指定的值无效
EIDRM:
信号集已被移除
EINTR:
系统调用阻塞时,被信号中断
EINVAL:
参数无效
ENOMEM:
内存不足
ERANGE:
信号所允许的值越界
7:
套接字
socket常被翻译成套接字或者插口,socket实际上就是网络上的通信端点。
使用者或应用程序只要连接到socket便可以和网络上任何一个通信端点连接,传送数据。
socket封装了通信的细节,在Linux系统,为使用者提供了类似文件描述符的操作方法,程序员可以不必关系通信协议内容而专注应用程序开发。
根据数据传送方式,可以把socket分成面向连接的数据流通信和无连接的数据报通信。
创建:
在使用socket通信之前,需要创建socket对象。
对应用程序员来说,soeket对象就是一个文件句柄,通常使用socket()函数创建socket()对象。
函数定义如下:
sys/socket.h>
intsocket(intdomain,inttype,intprotocol);
超时处理:
实际的网络通信数据常会因为各种网络故障导致传输失败,在应用程序里需要对数据发送和接收做对应的超时处理,超时指的是预先假定一次数据传输需要的时间,如果超过这个时间没有得到反馈,认为数据传输失败,socket库提供了两个强大的函数setsockopt()和getsockopt()用来设置套接字和得到套接字参数,函数定义如下:
intgetsockopt(ints,intlevel,intoptname,void*optval,socklen_t*optlen);
intsetsockopt(ints,intlevel,intoptname,constvoid*optval,socklen_toptlen);
多线程程序设计
线程是一种轻量级的进程。
于进程最大的不同是,线程没有系统资源。
线程是操作系统调度的最小单位,可以理解为一个进程是由一个或者多个线程组成的。
在操作系统内核中,是按照线程作为调度单位来调度资源的。
在一个进程内部,多个线程之间的资源是共享的。
也就是说,一个进程内部所有线程拥有相同的代码地址空间和数据空间,任意线程可以访问其他所有线程的数据。
多线程的优缺点:
提高应用程序响应。
这对图形界面的程序尤其有意义,当一个操作耗时很长时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术,将耗时长的操作置于一个新的线程,可以避免这种情况;
使多CPU系统更加有效,操作系统会保证当线程数不大于CPU数目时,不同的线程运行在不同的CPU上;
改善程序结构。
一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。
Linux系统开发多线程程序大多使用pthread库,pthread库是符合POSIX线程标准的一个应用库,提供了线程的管理和操作方法。
pthread库对线程操作的函数基本都以pthread开头,创建线程的函数定义如下:
intpthread_create(pthread_t*tidp,constpthread_attr_t*attr,void*(*start_rtn)(void),void*arg)
锁(同步)
互斥锁和条件变量是同步的架构模块;
互斥锁用户保护临界区;
读写锁:
只要没有线程在修改某个给定的数据,那么任意数据的线程都可以拥有该数据的读访问权;
仅当没有其他线程在读或者修改某个给定的数据时,其他线程才可以修改它;
文件系统
ext2文件系统是Linux系统使用最广泛的文件系统。
它的设计思想是由一系列逻辑上线性排列的数据块构成,每个数据块大小相同。
所有的数据块被划分成若干个分组,每个组包含相同个数的数据块,整个文件系统的布局。
ext3文件系统直接从ext2文件系统发展来的,完全兼容ext2文件系统。
目前ext3文件系统已经很稳定,用户可以直接过渡到ext3文件系统。
除增加了日志文件功能外,ext3文件系统的结构与ext2文件系统完全相同。
ext3既可以仅对meta-data进行日志操作,也可以同时对文件数据块做日志。
具体来说,ext3提供日志、预定和写回三种日志模式。
日志(Journal)模式:
预定(Ordered)模式:
写回(Writeback)模式:
ReiserFS文件系统:
与ext3文件系统不同,ReiserFS文件系统是一个完全重新设计的文件系统。
ReiserFS文件系统适合大数据量的存储需求,可以轻松管理超大文件。
ReiserFS借鉴了面向对象思想,该文件系统分成语义层和存储层。
其中,语义层用来管理命名空间和接口定义,存储层管理具体的磁盘空间。
语义层解析对象名然后通过键与存储层联系,存储层通过键确定数据在磁盘上的存储位置。
在ReiserFS文件系统中,键的值是唯一确定的。
以下是语义层和存储层的详细介绍。
1.语义层
2.存储层
JFFS文件系统是一个在闪存上使用广泛的读/写文件系统,普遍使用在嵌入式系统,目前使用最多的是第二版本,即JFFS2。
1.闪存的特性和限制
2.闪存转换层
3.JFFS2文件系统介绍
4.JFFS2文件系统的垃圾回收
5.JFFS2文件系统的缺点
cramfs是这个问题的一种解决方法。
cramfs文件系统是专门针对闪存设计的只读压缩的文件系统,其容量上限为256M,采用zlib压缩。
文件系统类型可以是ext2或ext3。
cramfs文件系统不需要一次性地将文件系统中的所有内容都解压缩到内存之中,而只是在系统需要访问某个位置的数据的时侯,马上计算出该数据在cramfs中的位置,将其实时地解压缩到内存之中,然后通过对内存的访问来获取文件系统中需要读取的数据。
cramfs中的解压缩以及解压缩之后的内存中数据存放位置都是由cramfs文件系统本身进行维护的,整个过程对用户透明,对开发人员来说,既方便,又节省了存储空间。
Linuxinit
Init是内核启动的用户级进程;
在/sbin/init目录中
shell
网络编程
学习分析协议的方法
网络协议一般都比较抽象,给人感觉枯燥。
学习网络协议需要一个直观的认识,推荐读者使用网络协议分析的工具分析协议。
目前有很多的网络协议分析工具,著名的Sniffer就是一款专业的网络协议分析利器,本书介绍一个比较流行的工具Ethereal,这是一个开源的网络协议分析工具,功能十分强大,使用libpcap库做数据包解析,使用GTK+库做界面,由于这两个库是跨平台的,所以Ethereal可以在多种平台使用。
Ethereal最大的特点是支持用表达式书写包过滤条件,同时支持常见协议的深度分析,如HTTP,SIP等。
Ethereal最新版本已经更名为WireShark,官方网站是http:
//www.wireshark.org,官方网站有软件的使用手册以及下载。
内核
进程管理
当一个用户进程被加载后,会进入就绪态,被加入到就绪态队列,CPU时间被轮转到就绪态队列后,切换到进程的代码,进程被执行,当进程的时间片到了以后被换出。
如果进程发生I/O操作也会提前被换出,并且存放到等待队列,当I/O请求返回后,进程又被放入就绪队列。
Linux系统对进程队列的管理设计了若干不同的方法,主要的目的是提高进程调度的稳定性。
系统调用
系统调用是Linux内核提供的,用户空间无法直接使用系统调用。
在用户进程使用系统调用必须跨越应用程序和内核的界限。
Linux内核向用户提供了统一的系统调用接口,但是在不同处理器上系统调用的方法各不相同。
中断机制
异常:
CPU内部出现的中断称为异常;
内核(2.6版)提供了三种不同的机制实现下半部:
软中断、tasklet、工作队列;
内核定时器:
软中断:
kenerl/softirq.c,最多有32个软中断
Structsoftirq_action{
Void(*action)(structsoftirq_action*);
Void*data;
}
软中断会被以下情况检查执行:
从一个硬件中断代码处返回时;
在ksoftirqd内核线程中;
在那些显示检查和执行待处理软中断的代码中,如网络子系统中。
进程调度
内核同步
自旋锁:
防止并发访问;
Seq锁:
write_seqlock();
Write_sequnlock();
时间管理
Jiffies:
系统启动以来产生的节拍总数;
Jiffy:
节拍间隔;
内存管理
使用虚拟内存技术的计算机,内存管理的硬件按照分页方式管理内存。
分页方式是把计算机系统的物理内存按照相同大小等分,每个内存分片称作内存页,通常内存页大小是4KB。
Linux内核的内存管理子系统管理虚拟内存与物理内存之间的映射关系,以及系统可用内存空间。
内存管理要管理的不仅是4KB缓冲区。
Linux提供了对4KB缓冲区的抽象,例如slab分配器。
这种内存管理模式使用4KB缓冲区为基数,然后从中分配结构,并跟踪内存页使用情况,比如哪些内存页是满的,哪些页面没有完全使用,哪些页面为空。
这样就允许该模式根据系统需要来动态调整内存使用。
4G的虚拟地址空间划分为----用户空间(0---3G)和内核空间(3G---4G)
虚拟内存和物理内存都分为大小固定的块,叫做页面,每个页面都有唯一的页面号,叫做PFN;
MMU:
以页为单位管理;
区:
页-------
获得页:
Structpage*alloc_page(unsignedintgfp_mask,unsignedintoredr)
Void*page_address(structpage*page)把物理地址转换为逻辑地址
释放页:
交换:
同一地址空间内的不同内存区间不能重叠;
Swap()函数实现内存交换;
8:
虚拟文件系统
虚拟文件系统,即VFS(VirtualFileSystem)是Linux内核中的一个软件抽象层。
它通过一些数据结构及其方法向实际的文件系统如ext2,vfat等提供接口机制。
通过使用同一套文件I/O系统调用即可对Linux中的任意文件进行操作而无需考虑其所在的具体文件系统格式;
更进一步,文件操作可以在不同文件系统之间进行。
9:
I/O层
字符设备:
不可以被随机访问;
块设备:
可以被随机访问;
10:
模块
Intmy_init(void)注册
Intmy_exit(void)删除