2014025673《嵌入式系统程序设计》第七周学习总结

2014025673《嵌入式系统程序设计》第七周学习总结

在本周,主要学习了管道及消息队列等相关知识。


一、FIFO

1.有名管道和无名管道的区别:

  • 无名管道:只能用于具有亲缘关系的进程之间。
  • 有名管道:突破了无名管道的限制,它可以使互不相关的两个进程实现彼此通信,在建立管道之后,两个进程就可以像普通文件进行读写操作一样进行操作。

2.阻塞打开和非阻塞打开的读写。

(1)对于读进程。

  • 若该管道是阻塞打开,且当前FIFO 内没有数据,则对读进程而言将一直阻塞到有数据写入。
  • 若该管道是非阻塞打开,则不论FIFO 内是否有数据,读进程都会立即执行读操作。即如果FIFO内没有数据,则读函数将立刻返回0。

(2)对于写进程。

  • 若该管道是阻塞打开,则写操作将一直阻塞到数据可以被写入。
  • 若该管道是非阻塞打开而不能写入全部数据,则读操作进行部分写入或者调用失败。

二、mkfifo()函数

mkfifo函数的作用是在文件系统中创建一个文件,该文件用于提供FIFO功能,即实名管道。

  • 相关函数
    pipe popen open umask
  • 函数头文件
 #include <sys/types.h>
 #include <sys/state.h>
  • 函数原型
    int mkfifo(const char *filename,mode_t mode)
  • 函数传入值
    • filename:要创建的管道
  • 函数传入值 mode:
O_RDONLY 读管道
O_WRONLY 写管道
O_RDWR 读写管道
O_NONBLOCK 非阻塞
O_CREAT 如果该文件不存在,那么就创建一个新的文件,并用第三个参数为其设置权限
O_EXCL 如果使用O_CREAT 时文件存在,那么可返回错误消息。这一参数可测试文件是否存在
  • 函数返回值
    成功:0; 出错:-1;
  • 函数说明
    mkfifo()会依参数pathname建立特殊的FIFO文件,该文件必须不存在,而参数mode为该文件的权限(mode%~umask),因此 umask值也会影响到FIFO文件的权限。Mkfifo()建立的FIFO文件其他进程都可以用读写一般文件的方式存取。当使用open()来打开 FIFO文件时,O_NONBLOCK旗标会有影响
    1.当使用O_NONBLOCK 旗标时,打开FIFO 文件来读取的操作会立刻返回,但是若还没有其他进程打开FIFO 文件来读取,则写入的操作会返回ENXIO 错误代码。
    2.没有使用O_NONBLOCK 旗标时,打开FIFO 来读取的操作会等到其他进程打开FIFO文件来写入才正常返回。同样地,打开FIFO文件来写入的操作会等到其他进程打开FIFO 文件来读取后才正常返回。

access()

  • 功能:检查某个文件的存取方式。
  • 原型:
    int access(const char *filename, int mode)
  • 参数:
    • filename要检查的管道路径及名字
    • mode要判断的模式
    • R_OK只判断是否有读权限
    • W_OK只判断是否有写权限
    • X_OK判断是否有执行权限
    • F_OK只判断是否存在
  • 返回值:
    0:指定的存取方式有效;-1:指定的存取方式无效
  • 实际操作:
    实际操作的实验过程下实验楼中进行,在进行实际操作时,要同时打开两个终端进行试验。

消息队列的应用

一、函数介绍

消息队列的实现包括创建或打开消息队列msgget()、添加消息msgsnd()、读取消息msgrcv()和控制消息队列msgctl()这4 种操作。

二、具体函数要点

1.msgget()函数
所需头文件

    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>

函数原型
int msgget(key_t key, int msgflg)
函数传入值
key:消息队列的键值,多个进程可以通过它访问同一个消息队列,其中有
个特殊值IPC_PRIVATE。它用于创建当前进程的私有消息队列
函数返回值
成功:消息队列ID 出错:-1
2.msgsnd()函数
所需头文件

    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>

函数原型:
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)
函数传入值

    msqid:消息队列的队列ID
    msgp:指向消息结构的指针。该消息结构msgbuf 通常为:
    struct msgbuf
    {
    long mtype; /* 消息类型,该结构必须从这个域开始 */
    char mtext[1]; /* 消息正文 */
    }

函数返回值
成功:0;出错:-1
3.msgrcv()函数
所需头文件

    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>

函数原型:
int msgrcv(int msgid, void *msgp, size_t msgsz, long int msgtyp, int msgflg)
函数传入值
msqid:消息队列的队列ID
msgp:消息缓冲区, 同于msgsnd()函数的msgp
msgsz:消息正文的字节数(不包括消息类型指针变量)
msgtyp:
等于0:接收消息队列中第一个消息
大于0:接收消息队列中第一个类型为msgtyp 的消息
小于0:接收消息队列中第一个类型值不小于msgtyp 绝对值且类型值又最小的消息
函数返回值
成功:0
出错:-1
4.msgctl()函数
所需头文件

    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>

函数原型
int msgctl (int msgqid, int cmd, struct msqid_ds *buf )
函数传入值
msqid:消息队列的队列ID
命令参数
IPC_STAT:读取消息队列的数据结构msqid_ds,并将其存储在
buf 指定的地址中
IPC_SET:设置消息队列的数据结构msqid_ds 中的ipc_perm 域(IPC 操作权限描述结构)值。这个值取自buf 参数
IPC_RMID:从系统内核中删除消息队列
buf:描述消息队列的msgqid_ds 结构类型变量
函数返回值
成功:0;出错:-1

思想与感悟:

通过课上的学习的课下的练习,掌握了有名管道和无名管道的区别,体会了两个进程间传输。在消息队列部分,体会了消息队列和管道传输之间的区别,消息队列相对于管道传输更加灵活和方便。

posted @ 2017-06-11 13:10  6班-15-李东冉  阅读(150)  评论(0编辑  收藏  举报