Unix程序设计基础第三讲_第1页
Unix程序设计基础第三讲_第2页
Unix程序设计基础第三讲_第3页
Unix程序设计基础第三讲_第4页
Unix程序设计基础第三讲_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Unix程序设计基础 第三讲2004-2-101Reviews of last class进程独立地址空间的指令序列五种状态基本状态:新建,就绪,运行,睡眠,僵死状态转换图进程ID,子进程,父进程Unix下的多进程编程fork与execve:进程的创建与程序的运行wait,waitpid:回收子进程的退出状态2Reviews of last class信号是Unix操作系统用来通知进程发生了某种事件的一种手段。也称为软件中断几个常用的信号信号编程signal与sigaction:改变信号动作alarm:设置闹钟不可重入函数:在函数返回之前不可再次被调用,如printf,malloc。3信号编程

2、(续)功能更强的改变信号动作函数:sigaction。解决早期signal函数的不可靠问题:在信号处理过程中再次收到这个信号怎么办?一般情况下用不到,请自己看书。发送信号函数kill与raise。函数原型:#include int kill(pid_t pid, int sig);int raise(int sig);4信号的发送kill给进程号为pid的进程发送一个sig信号pid 0:发送给进程ID为pid的进程pid = 0:发送给与自己同组,并且自己有权限向其发送的进程pid -1:发送给进程组ID为-pid的进程,并且自己有权限向其发送的进程pid = -1:所有自己有权限向其发送信

3、号的进程5信号的发送raise调用给自己发关一个sig信号。因此,raise(sig);等价于kill(getpid(), sig);发送信号的shell命令:kill。在默认情况下发送的是SIGTERM信号$ kill 12345 等价于 $ kill TERM 12345,都是向进程12345发送一个SIGTERM信号。$ kill KILL 12345,向进程12345发送一个SIGKILL信号6信号的屏蔽在一段时间内屏蔽掉某些信号,让当前进程接收不到这些信号。与忽略信号(remember?)不同,被屏蔽的信号会被保存起来(但不排队),在屏蔽解除后会被进程收到。注意一点:一般情况下用si

4、gnal函数设置信号动作,在某信号处理过程中,该信号是被屏蔽的。7实例:SIGCHLD信号不详细讲关于信号屏蔽的系统调用,因为不是很重要,而且内容太多。但我想通过一个例子来让大家了解信号屏蔽:某个进程通过调用fork创建多个子进程: for (i = 0; i n; i+) if (pid = fork() = 0) break; 8实例:SIGCHLD信号当父进程给束之前,必须调用wait来回收子进程的退出状态,如: for (i = 0; i 0) ; 13进程间通信(IPC)著名Unix与网络专家Richard Stevens,有多本Unix著作,本本经典。Advanced Progra

5、mming In the Unix Environment (APUE)TCP/IP Illustrated volume 1, 2, 3Unix Network Programming (UNP) volume 1, 21999年9月30号去世TT,UNP volume 3没有写完。14进程间通信(IPC)UNP volume 2:用了一本书来讲IPC所以,我不可能在半节课之内涵盖IPC的各个方面,只能讲一些最基本,也是最重要的:管道通信FIFO通信15管道通信最古老的Unix IPC工具,一个进程从管道一头写数据,另一个进程从管道另一头读数据。相通信方式是单向的。(演示shell下的管道通

6、信)先了解一下进程创建过程中文件描述字的继承。16单个进程打开两个文件17fork之后18管道通信创建管道pipe函数原型:#include int pipe(int fdes2); pipe函数成功后,内核打开两个文件描述字fdes0,fdes1。fdes0输入端,fdes1为输出端。19当进程调用了pipe20fork被调用后21两个进程分别关闭一个端22int main(void) pid_t pid; int fdes2; if (pipe(fdes) 0) perror(“pipe”); exit(1); if (pid = fork() 0) close(fdes0); write

7、(fdes1, “Hmmmmmmmmmmm”, 12); /* 1 2 3 4 5 6 7 8 9 0 1 2 */ else char buf4096; ssize_t n; close(fdes1) n = read(fdes0, buf, 4096); if (n = 0) bufn = 0; printf(“%sn”, buf); return 0;23管道破裂如果一个管道的读端已经关闭,进程还继续向写端写数据,如: pipe(fdes); close(fdes0); write(fdes1, “Let me die”, 10); 则进程会收到一个SIGPIPE信号,表示管道破裂。默认

8、动作为结束进程。读一个写端已经关闭的管道则read返回0。24FIFO通信FIFO是一种特殊设备文件,又称为有名管道。操作方法与普通文件相同。对于普通文件,我们可以从文件任一位置读数据,也可以从任一位置写数据;数据读完不会消失。但对FIFO来说,我们只能从文件头读数据,从文件尾写数据。数据被某进程读走之后就会消失。(实例演示)25FIFO相关的调用和shell命令创建设备文件FIFO:mkfifo 函数原型: #include #include int mkfifo(const char *, mode_t mode);shell命令: $ mkfifo m 0600 fifo126线程简介L

9、inux下的clone系统调用可以实现比fork更多的功能,比如让创建出来的子进程分享父进程的地址空间。习惯上把这些与父进程分享地址空间的子进程称为线程(Thread)。不同的系统对线程有不一样的定义,但相同之处是它比进程的开消小,因此也被称为是轻量级进程。27线程简介因为地址空间共享使得线程之间的通信非常方便,但必须特别注意数据一致性。Posix定了标准的线程接口,请参考UNP volume 1,Chapter 2328高级IOI/O的方式有很多种,我们之前使用的IO方式的特点是:单路:只能等待一个fd可读或可写阻塞:睡眠直到fd可读或可写同步:read和write必须结束才返回?因此有与之

10、对应的:多路:同时等待多个fd可读或可写非阻塞:fd不可读或不可写立即返回异步:I/O没有结束read和write也可返回29非阻塞I/O以非阻塞方式打开一个文件,如:fd = open(“love.txt”, O_RDWR | O_NONBLOCK, 0);也可以用fcntl让一个已经打开的文件描述字变成非阻塞: flags = fcntl(fd, F_GETFL, 0); fcntl(fd, F_SETFL, flags | O_NONBLOCK);30非阻塞I/O对一个非阻塞的fd来说,如果它无数据可读,则read(fd, );返回-1,errno的值被置为EAGAIN;同样,如果它暂时

11、不可写,write(fd, );返回-1,errno=EAGAIN。(阻塞式I/O在这两种情况下都是等待)。注意:应当区为无数据可读与文件已经读到结尾。后者read返回0,无论阻塞否。非阻塞I/O经常与多路I/O配合使用。31多路I/O想像一个fd集合fdset,以及一个函数fun,我们指定:调用fun(fdset)进程进入睡眠,直到fdset中至少有一个fd可读,此时fun返回并把可读的fd保存在fdset中。这样做的好处是,我们可以同时从多个fd中等待数据,如果某一个可读我们就从中读取,否则就睡眠。32多路I/OUnix下就存在这种的一个fun,但它的功能更加强大。它就是select(在有的系统下为poll,Linux都支持) 函数原型:#include

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论