- 198
- 0
- 约1.37万字
- 约 15页
- 2016-04-23 发布于天津
- 举报
实验三线程控制和进程间通信-unix操作系统实验室
实验 线程控制和进程间通信
一、实验目的
。
二、实验内容:
三、思考
四、实验指导
一
无名管道通过pipe()系统调用创建,它具有如下特点:
它只能用于具有亲缘关系的进程(如父子进程或者兄弟进程)之间的通信。
管道是半双工的,具有固定的读端和写端。虽然pipe()系统调用返回了两个文件描述符,但每个进程在使用一个文件描述符之前仍需先将另一个文件描述符关闭。如果需要双向的数据流,则必须通过两次pipe()建立起两个管道。
管道可以看成是一种特殊的文件,对管道的读写与文件的读写一样使用普通的read、write等函数,但它不是普通的文件,也不属于任何文件系统,而只存在于内存中。
2.pipe系统调用
(1)函数原型
#include unistd.h
int pipe(int filedes[2]);
(2)参数
filedes参数两个文件描述符,filedes[0]指向管道的读端,filedes[1]指向管道的写端filedes所指的数组中,其中filedes[0]用于读管道,filedes[1]管道EMFILE:进程使用的文件描述符过多
ENFILE :系统文件表已满
EFAULT :非法参数filedes
3.无名管道的阻塞型读写
管道缓冲区有4096B的长度限制,因此,采用阻塞型读写方式时,当管道已经写满时,写进程必须等待,直到读进程取走信息为止。同样,读空的管道时,也可能会引起进程阻塞。
当管道大小(管道缓冲区中待读的字节数)为p,而用户进程请求读n个字节时:
若不存在写进程:
① p=0,则返回0;
② 0pn,则读得p个字节,返回p,管道缓冲区中还剩0个字节;
③ p≥n,则读得n个字节,返回n,管道缓冲区中还剩p-n个字节;
若存在写进程,且写进程没因写管道而阻塞时:
① p=0,读进程阻塞等待数据被写入管道;
② 0pn,则读得p个字节,返回p,管道缓冲区中还剩0个字节;
③ p≥n,则读得n个字节,返回n,管道缓冲区中还剩p-n个字节;
若存在写进程,且写进程因写管道而阻塞时:
①0pn,则读管道,当管道缓冲区变空时,阻塞,等待数据被写入。最后,返回实际读得的字节数;
②p≥n,则读得n个字节,返回n,管道缓冲区中还剩p-n个字节。
当管道缓冲区中有u个字节未用,而用户进程请求写入n个字节时:
若不存在读进程,则向写管道的进程将发SIGPIPE信号,并返回-EPIPE。
若存在至少一个读进程:
① u<n≤4096 则写进程等待,直到有n-u个字节被释放为止,写入n个字节,返回n;
② n>4096 则写入n个字节(必要时等待)并返回n;
③ u≥n 写入n个字节,返回n。
4.无名管道使用实例
//pipeDemo.c
#include errno.h
#include stdio.h
#include stdlib.h
#include unistd.h
#define BUFNUM 60
int main(void)
{
int n;
int fd[2];
pid_t pid;
char buf[BUFNUM];
if (pipe(fd) 0)
{
fprintf(stderr,Creat Pipe Error:%s \n,strerror(errno));
exit(EXIT_FAILURE);
}
if ((pid = fork()) 0)
{
fprintf(stderr,Fork Error:%s \n,strerror(errno));
exit(EXIT_FAILURE);
}
if (pid 0) /* parent */
{
close(fd[0]);
write(fd[1], Im your father.\n, 17);
write(fd[1], Im waiting for your termination.\n, 35);
wait(NULL);
}
else /* child */
{
close(fd[1]);
n = read(fd[0], buf, BUFNUM);
printf(%d bytes read:%s,n,buf);
}
return 0;
}
上述程序父进程创建一个管道,然后再创建一个子进程,由于子进程是父进程的精确拷
原创力文档

文档评论(0)