本周我们学习了,有名管道和消息队列的传输和接收,并且在课上和课下实验楼中进行了程序的验证和操作。
管道
1.特点
它只能用于具有亲缘关系的进程之间的通信(也就是父子进程或者兄弟进程之间)。
它是一个半双工的通信模式,具有固定的读端和写端。
管道也可以看成是一种特殊的文件,对于它的读写也可以使用普通的 read()和 write()等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内核的内存空间中。
管道读写注意点
只有在管道的读端存在时,向管道写入数据才有意义。否则,向管道写入数据的进程将收到内核传来的 SIGPIPE 信号(通常为 Broken pipe 错误)。
向管道写入数据时, Linux 将不保证写入的原子性,管道缓冲区一有空闲区域,写进程就会试图向管道写入数据。如果读进程不读取管道缓冲区中的数据,那么写操作将会一直阻塞。
父子进程在运行时,它们的先后次序并不能保证,因此,在这里为了保证父子进程已经关闭了相应的文件描述符,可在两个进程中调用 sleep()函数。
对于读进程。
若该管道是阻塞打开,且当前 FIFO 内没有数据,则对读进程而言将一直阻塞到有数据写入。
若该管道是非阻塞打开,则不论 FIFO 内是否有数据,读进程都会立即执行读操作。即如果 FIFO
内没有数据,则读函数将立刻返回 0。
对于写进程。
若该管道是阻塞打开,则写操作将一直阻塞到数据可以被写入。
若该管道是非阻塞打开而不能写入全部数据,则读操作进行部分写入或者调用失败
消息队列函数说明
消息队列的实现包括创建或打开消息队列、添加消息、读取消息和控制消息队列这 4 种操作。其中创建
或打开消息队列使用的函数是 msgget(),这里创建的消息队列的数量会受到系统消息队列数量的限制;
添加消息使用的函数是 msgsnd()函数,它把消息添加到已打开的消息队列末尾;读取消息使用的函数是
msgrcv(),它把消息从消息队列中取走,与 FIFO 不同的是,这里可以指定取走某一条消息;最后控制消
息队列使用的函数是 msgctl(),它可以完成多项功能
本周实验内容如下:
编辑、编译、运行下列程序:
有名管道部分:fifo_write.c 和 fifo_read.c
消息队列部分:msgsnd.c和msgrcv.c