ImageVerifierCode 换一换
格式:DOCX , 页数:50 ,大小:905.07KB ,
资源ID:3680648      下载积分:2 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/3680648.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Unix实践编程入门笔记.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Unix实践编程入门笔记.docx

1、Unix实践编程入门笔记第一章 Unix 系统编程概述第二章 1.2a) 内存空间时用来存放程序和数据的,所有程序必须需要在内存空间中运行b) 而容纳操作系统的内存空间称为系统空间,容纳应用程序的内存空间叫做用户空间c) 操作系统也是一种程序d) 操作系统也称为内核e) 第三章 1.3 理解系统编程a) 内核提供服务以方便系统程序可以直接访问系统资源b) 系统资源i. 处理器:处理指令ii. 输入输出(I/O)iii. 进程管理iv. 内存v. 设备vi. 计时器:内核可以通过系统调用向应用程序提供计时器服务vii. 进程间通信viii. 网络c) 如何理解:i. 分析程序ii. 学习系统调用

2、iii. 编程实现第四章 1.4 用户角度理解unixa) 用户登录到unix后 全部叫个shell进程b) 每个用户有自己的shell进程c) 目录操作d) 文件操作e) unix 不支持 恢复被删除的文件功能,因为unix是多用户系统,当一个文件被删除掉以后,所占用的内存空间可能被立刻分配给其他用户f) 文件都有三组许可权限i. user group other第五章 1.5 从系统的角度来看unix第六章 1.6 动手实践a) 实现一个more第二章 用户 文件操作与联机帮助 编写who命令 open 打开文件是内核提供的服务,如果打开过程中内核检测到错误就会返回-1; 当一个文件已经被

3、打开,unix并不禁止一个文件被同时多个进程访问 如果文件被顺利打开,内核会返回一个正整数值,即文件描述符,这个是用来唯一表示进程和文件建立的连接.如果一个文件被打开多次,所建立的连接不同,文件描述符也不同. close 系统会调用 关闭进程和文件fd之间的连接. 提升文件I/O效率的方法: 使用缓冲 注销过程 打开utmp文件 从utmp中找到包含你所在终端的登陆记录 对当前记录做修改 关闭文件 处理系统调用中的错误 错误种类errno 在errno.h中或man 3 error 不同错误需要不同处理 perror显示出错信息 perror(Cannot open file)第三章 目录与文

4、件属性 磁盘上的文件和目录被组成一个目录树,每个节点都是目录或文件 每个文件都位于某个目录中,在逻辑上没有驱动器或者卷 目录 一种特殊的文件 类似utmp文件 是文件的列表,是记录的序列,每条记录对应一个文件或子目录 通过readdir来读取目录中的当前记录的指针 记录类型为struct dirent opendir 打开一个目录 readdir 返回目录中的当前项 closedir 关闭一个目录 字段编码 把多种信息编码到一个整数的不同字段中是一种常用技术 掩码 为了比较,把不需要的地方置零,这种技术叫做掩码 masking 将用户/组ID转换成字符串 /etc/passwd 包含用户列表

5、/etc/passwd 并没有包括所有的用户 /etc/group 是组的列表 UID没有对应的用户名 用户可以同时属于多个组 通过getpwuid 来得到完整的用户列表 通过getgrgid来访问组列表 stat st_mode成员包含16位,其中四位用作文件类型,9位用作许可权限,剩下的三位用作文件特殊属性. 三位中的第一位叫做set-user-ID SUID经常用来给某些程序提供额外的权限 可以通过sys/stat.h定义的掩码来检验一个程序是否有SUID位 第二位是 set-group-ID 修改文件的权限 文件类型 普通文件,目录文件,socket文件,符号链接文件,命名管道文件 文

6、件一旦建立,类型就无法修改 chown 更改文件的用户 chown(file, 200, 20); 将用户ID改为200, 将组ID改为40 chgrp 修改文件的所有组 文件大小 可以用creat将文件大小置0 时间 每个文件都有3个时间 最后修改时间,最后访问时间和属性最后修改时间 utime系统调用可以用来设置最后修改时间和最后访问时间 shell命令touch 也可修改文件的最后访问时间和最后修改时间 文件名 修改文件名 create(char * old, char * new)第四章 文件系统 文件操作命令o ln x x-link x-link 指向xo ln 命令的作用是生成一

7、个链接 链接是指向文件的一个指针,表明,x-link和x都指向硬盘上的统一数据块o lsx-ling 将ls的输出作为文件x-link的内容 目录树的命令o ls -R 列出指定目录以及其子目录的所有内容 目录树的深度几乎没有限制 Unix文件系统的内部结构o 第一层 从磁盘到分区o 第二层从磁盘到块序列o 第三层,从块序列到三个区域的划分 unix 将磁盘块分成三个部分任何一部分都由很多有序的磁盘块组成,文件系统就是由这三部分组成o 超级块 文件系统中的第一块,被称为超级块,存放文件系统本身的结构信息o i-节点表 每个文件的属性被记录在i-节点的结构中,所有节点具有相同的大小 每个节点都通

8、过位置来标识,例如标识为2的节点位于第三个位置o 数据块 保存文件的内容 创建一个文件的过程o 存储属性 找到一个空的i-节点,内核将文件的信息记录在其中o 存储数据 在内核中自由块中招出3个自由块o 记录分配情况 文件内容按顺序存放在自由块中,内核在i-节点的磁盘分布区记录了上述的自由块序列,o 添加文件名到目录 内核将接口添加到目录文件(节点,filename) 文件系统的实现:目录的工作过程o 可以通过 ls -1ia demodir 来查看目录的内容,输出的为文件名对应的i 节点号o ls -i查看一个文件的i 节点号o 对open的每次调用都是先查找文件名,然后得到节点号,通过节点号

9、再得到文件属性 最终找到文件内容o 存在间接块: 存放的是更多磁盘块 使用ls -iaR可以列出一棵树中的所有文件的i节点号 如果目录中有两个连接的状态完全相同,它们称为指向文件的硬链接.内核记录了一个文件的链接数. mv仅仅是调用了系统命令renameo rename: 复制链接至新的名字/位置,删除原来的链接 cd 调用了系统函数 chdiro chdir改变进程的当前目录,进程有一个存放当前目录节点好的变量,从一个目录进入两一个目录只是改变那个变量的值 link和rename 不可以创建跨域设备的链接和拒绝在不同的文件系统间进行节点号的转移. df -i命令查看各分区inode 情况 d

10、f -h 可以查看各个分区的使用情况第五章 连接控制:学习 sty 设备就像文件:o unix中各种声卡,终端,鼠标和磁盘文件是同一种对象.每个设备都有一个文件名,一个i节点号,一个文件所有者,一个权限位的集合和最近修改时间o 设备文件的属性o 设备文件和文件大小 设备文件是链接而不是容器,不存储击键数和点击数. 设备文件的i节点存储的是指向内核的程序的指针,而不是文件大小和存储列表 运行ls /dev/pts/0 -al 输出 在文件大小位置的两个数字136,0前者是主设备号,后者是从设备号 主设备号:确定除了该设备实际的子程序 从设备号:作为参数传输到该子程序o 设备文件和权限位 只有文件

11、的所有者有读的权限,二同一组的tty成员拥有写设备的权限o 设备文件和i节点 文件类型的区别体现在i-节点上 i节点可以是磁盘文件,也可以是设备文件,i 节点的类型被记录在结果stat的成员变量 st_mode类型区域中 read 在i节点先获取其类型,如果是磁盘文件则通过分配表来读取数据,如果是设备文件,则调用该设备驱动程序的read部分来读取数据 设备与文件的不同o 磁盘链接具有缓冲这样一个属性.到终端的链接则不同,进程需要尽快把终端的数据传送出去 硬盘链接的属性o 缓冲 通过修改控制变量改变文件描述符的动作 例关闭磁盘缓冲 生成一个系统调用,将控制变量从文件描述符 复制到进程 修改这个复

12、制过来的控制变量 将新的设置安置到进程代码中o 自动添加模式 为了避免同时对一个文件描述符写入出现的竞争现象 当O_APPEND被置位,lseek和write组合成一个原子操作,即不可分割 s = fcntl(fd, F_GETEL); s |= O_APPEND; result= fcntl(fd, F_SETFL,s); write(fd, &rec, 1); 终端连接的属性o 终端驱动程序 终端和进程之间由终端驱动器连接,处理进程和外部设备间数据流的内核子程序被称为终端驱动程序,或者tty驱动程序o stty命令 可以让用户读取和修改tty的设置o stty 关于设置 输入: 输出: 控

13、制:字符如何表示 位的个数,位的奇偶性 本地:如何处理来自驱动程序内部的字符第六章 终端控制和信号 软件工具与针对特定设备编写的程序o 对磁盘文件和设备文件不加以区分的程序被称为软件工具o 事实上大多数进程自动将前三个文件描述符打开,它们不需要调用open()来建立连接o 用户程序的常用设置 立即响应击键事件 有限的输入集 输入的超时 屏蔽 ctrl-c 终端驱动程序的模式o 规范模式 缓冲和编辑包含规范处理 例如 回显,缓冲,编辑,控制处理o 非规范模式 stty -icanon 关闭回显,关闭缓冲 这样输入什么字符后,将直接传递给用户程序o raw模式 阻塞与非阻塞输入o 当调用getch

14、ar 或read从文件描述符读取输入时,这些调用会等待输入o 阻塞不仅仅是终端连接的属性,而是任何一个打开的文件的属性 程序可以通过fcntl或open为文件描述符启动非阻塞输入 阻塞模式是必须等一个阻塞条件解除后进程才能继续执行. 非阻塞模式是不管条件满不满足都不停地执行下去 信号o Ctrl-C做了什么 用户输入 C-c 驱动程序 收到字符 匹配VINTR和ISIG的字符被开启 驱动程序调用信号系统 信号系统发送SIGINT给进程 进程收到SIGINT 进程消亡o 每个信号都有一个数字编码,中断信号通常是编码2o 信号来源 用户 发送C-c 或者其他分配给信号控制字符 内核 当进程出错,内

15、核给进程发送一个信号,如非法段存取,浮点数溢出 进程 一个进程可以和两一个进程通过信号通信o 进程如何处理信号 默认处理,通常消亡 忽略信号 调用一个函数 signal(int signum, void (* action)(int) action可以是函数名和SIG_IGN忽略信号和SIG_DFL 将信号恢复为默认处理 两个之一 在出程序装载了signal()函数后,如果进程遇到对应的signal,将会进入到对应的处理函数,然后再跳转到前一个位置,就像子过程调用o 进程终止 unix 有两个信号是不能被忽略和捕捉的第七章 事件驱动编程:编写一个vedio游戏 sleepo linux中的sl

16、eep(n) 函数 是将当前进程挂起n秒,或者在此期间被一个不能忽略的信号的到达所唤醒o sleep是如何工作的 设置闹钟的秒数 睡觉直到闹钟响起o 系统中每一个进程都有一个私有的闹钟,时间一到,时钟就发送一个信号SIGALARM给进程o sleep函数 为SIGALRM设置一个处理函数 调用alarm(num_seconds); 调用pause,动用pause挂起进程 直到信号到达,任何信号都可以唤醒进程,而非仅仅等待SIGALRM 间隔计时器o 每个进程有3个独立的计时器,每个计时器都有两个设置:初始间隔和重复间隔. 添加精度更高的时延 usleepo usleep(n) 将进程挂起n微秒

17、,直到一个不能忽略的信号到达 三种计时器o ITIMER_REAL 不管程序在用户态还是核心态,计时器都会及时,当计时器用尽,发送信息o ITIMER_VIRTUAL 只记录用户态的运行时间,计时器用尽发送消息o ITIMER_PROF 这个计时器在进程运行于用户态或由该进程调用而陷入核心态时计时.当这个计时器用尽 发送SIGPROF 两种间隔o 初始和重复 每个间隔计时器的设置都有这样两个参数:初始时间和重复间隔 it_value和it_interval 如果不需要重复将interval设置为0 把两个时钟都关掉的话 value设置为0o 通过设置 struct itimerval中的值 然

18、后将这个结构体通过调用setitimer传给计时器,读取计时器的设置用getitimer 计算机有几个时钟o 每当内核收到系统时钟脉冲,它遍历所有的间隔计时器,使每个计数器减一个时钟单位,如果进程A的计数器达到0的时候,内核发送SIGALRM给进程A.如果进程A已经设置了计时器的it_interval值,内核将这个值复制到it_value计数器.否则关掉这个计数器 信号处理:使用signalo POSIX Unix型可移植操作系统接口的信号处理模型o 处理多个信号 捕鼠器,当信号或老鼠被捕获,信号处理函数或捕鼠器就失效,再每次捕获后需要重新设置 不可靠的信号 两个sigints杀死进程 sig

19、y打断sigx的处理函数 sigx打断sigx的处理函数 递归调用同一个处理函数 忽略第二个信号 阻塞第二个信号直到第一个处理完毕 被中断系统调用o 信号机制其他弱点 不知道信号被发送的原因,只知道是什么类型的信号 处理函数中不能安全的阻塞其他消息 处理多个信号 sigactiono #include o #include o #include o o int i =0;o int main(int argc, const char *argv)o o struct sigaction newhandler;o sigset_t blocked;o void inthandler();o ch

20、ar x128;o o newhandler.sa_handler = inthandler;o newhandler.sa_flags = SA_RESTART;o o sigemptyset(&blocked);o sigaddset(&blocked, SIGQUIT);o newhandler.sa_mask = blocked;o o if(sigaction(SIGINT, &newhandler, NULL)= -1)o perror(sigaction down);o else o while (1) o fgets(x, 128, stdin);o printf(input:

21、%sn, x);o o o return 0;o o o void inthandler()o o +i;o int x = i;o printf(Called with signal %dn, x);o sleep(x);o printf(ok this signal%d donen, x);o sleep(x);o 防止数据损毁o 临界区 一段修改一个数据结构的代码如果在运行时被打断,将导致数据的不完整或损毁,这段代码称为临界区 在程序处理信号的时候必须决定那一段代码是临界区并设法保护 保护临界区的简单方法就是阻塞和忽略将要使用或修改特定数据的信号o 阻塞信号 sigprocmask和si

22、gsetops 处理一个信号阻塞另一个要设置sa_mask位 是sigset_t类型 定义了一个信号集 信号挡板 任何时候一个进程都有一些信号被阻塞,这个信号集就是信号挡板 sigprocmask可以修改这个信号集 sigprocmask(int how, sonst sigset_t *sigs, sigset_t *prev); how 如何修改信号挡板,依次是添加,删除和替换 SIG_BLOCK SIG_UNBLOCK SIG_SET sigs 指向信号列表的指针 prev 指向之前的信号挡板的指针 或者是null 用sigsetops 构造信号集 sigemptyset(sigset_

23、t *setp) 清除setp指向的所有信号 sigfillset(sigset_t *setp) 添加所有信号到setp指向的列表 sigaddset(sigset_t *setp, int signum) 添加signum到setp指向的列表 释放资源时 恢复获取时的状态是个好习惯o 重入代码 可重入 如果一个函数或者信号处理在激活状态下能被调用并且不引起任何问题就称之为可重入的 在sigaction设置时 设置为 SA_NODEFER来允许函数递归调用,反之清除此位来阻塞信号 如果处理不可重入则必须阻塞信号,如果阻塞 则有可能丢失信号o kill:从另一个进程发送信号 一个进程可以通过k

24、ill系统调用向另一个进程发送信号 int kill(pid_t pid, int sig) pid 目标进程pid sig 要被发送的信号 返回值: -1失败,0 成功 输入信号:异步IOo 硬件实现第八章 编写sh 学习进程 ps就是运行中的程序o WCHAN 程序休眠的原因 进程管理与文件管理o 文件包含数据o 进程包含可执行代码 内存和程序o 内存可看做由页面构成的数组,将进程分割到不同的页面o 一个进程不一定必须占用连续的内存o 内核要找到一些用来存放程序指令和数据的空闲内存页,内核还要建立数据结构来存放相应的内存分配情况和进程属性 shell的功能o shell进程控制和程序控制的

25、一个工具o 运行程序 shell将应用程序载入内存并运行,程序启动器o 管理输入和输出 shell可以用| 来将输入输出重定向,这样就可以告诉shell 将进程的输入输出连接到一个文件或是其他的进程o 编程 shell 带有变量和流程控制的编程语言 shell 如何运行程序o 用户键入a.outo shell建立一个新的进程来运行这个程序o shell 将程序从磁盘载入o 程序在它的进程中运行直到结束o 即学会o 运行一个程序o 建立一个进程o 等待exit() 一个程序如何调用另一个程序o execvp(progname, arglist) 将指定的程序复制到调用它的进程o exc系统调用从

26、当前进程中把当前程序的机器指令删除,然后在空的进程中载入调用指定的程序代码,最后运行这个新的程序,exec调整进程的内存分配,相同进程,不同内容 如何建立新的进程o 一个进程调用fork 来复制自己 分配新的内存块和内核数据结构 复制原来的进程到新的进程 向运行进程集添加新的继承 将控制返回给两个进程o 新的进程从fork返回的地方开始运行o fork()在子进程中返回的是0,在父进程返回子进程的进程号 父进程如何等待子进程退出o 进程调用wait等待子进程结束o 解释wait() wait挂起调用它的进程直到得到这个进程的子进程的一个结束状态,wait返回结束进程的pid,如果调用的进程没有

27、子进程也没有得到终止状态值,wait 返回-1 wait暂停调用它的进程直到子进程结束,然后wait取得子进程结束时传给exit的值 最终子进程会结束任务并调用exit(n) n是0-255的一个数字 int status wait(&status), 最终status的值就是exit(n)中的no 例 pid = fork() switch(pid): case -1: perror(fork failed!); exit(-1); case 0 :/说明是子进程 execvp(ls, arglist); perror(execvp failed!)/如果运行无误的话 子进程是运行不到此部分

28、的 exit(-1); default: while(wait(NULL)!=pid);o 退出主进程的办法只能是ctrl-c 但是如果在子进程等待的时候按了ctrl-c 则会将两个进程全部杀死o 因为键盘信号发给所有连接的进程,可以通过之前学习的知识装填相应的信号处理函数 对相应进程收到的信号进行处理o unix提供方法来建立全局变量.即是利用环境 exit 和 exec的其他细节o 那些已经死亡但是没有exit赋值的进程为僵尸进程,ps会将其列为defuncto 系统调用_exit() 关闭所有的文件描述符和目录描述符 将置为进程的 如果父进程调用或者来等待子进程结束,则通知父进程 向父进程发送SIGCHLD 如果子进程的父进程退出了,子进程也会继续运行,并成为init进程的子进程 exec家族o execl() l是list的意思 execl(fullname, arg0, arg1, .);o execlp() p是path的意思 会在环境变量中来找第一个参数指定的程序 execlp(filename, arg0, arg1, .);第九章 可编程的shell shell变量和环境 shell的编程特征o 变量,I/O 和 i

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1