博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2014025674(16) 《嵌入式系统程序设计》第七周学习总结
阅读量:5333 次
发布时间:2019-06-15

本文共 5465 字,大约阅读时间需要 18 分钟。

本周学习了第八章的主要内容主要包括两大部分分别为:

 

一、有名管道FIFO

1.有名管道说明

  • 定义:有名管道的出现突破了只能用于具有亲缘关系的进程之间,这就大大地限制了管道的使用限制,它可以使互不相关的两个进程实现彼此通信。该管道可以通过路径名来指出, 并且在文件系统中是可见的。在建立了管道之后,两个进程就可以把它当作普通文件一样进行读写操作, 使用非常方便。
  • 注意:FIFO 是严格地遵循先进先出规则的,对管道及 FIFO 的读总是从开始 处返回数据,对它们的写则把数据添加到末尾,它们不支持如 lseek()等文件定位操作。 有名管道的创建可以使用函数 mkfifo(),该函数类似文件中的 open()操作,可以指定管道的路径和打开的模式。
  • 对阻塞打开和非阻 塞打开的读写进行讨论:

          (1)对于读进程。

                  若该管道是阻塞打开,且当前 FIFO 内没有数据,则对读进程而言将一直阻塞到有数据写入。

                  若该管道是非阻塞打开,则不论 FIFO 内是否有数据,读进程都会立即执行读操作。即如果 FIFO 内没有数据,则读函数将立刻返回 0。

          (2)对于写进程。

                  若该管道是阻塞打开,则写操作将一直阻塞到数据可以被写入。

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

2.mkfifo()函数格式

  •  mkfifo()函数语法要点

                                      

  • FIFO 相关的出错信息 

                                       

 

3.使用实例

  • 以下是写管道的程序:
/* fifo_write.c */#include 
#include
#include
#include
#include
#include
#include
#define MYFIFO "/tmp/myfifo" /* 有名管道文件名*/#define MAX_BUFFER_SIZE PIPE_BUF /*定义在于 limits.h 中*/int main(int argc, char * argv[]) /*参数为即将写入的字符串*/{ int fd; char buff[MAX_BUFFER_SIZE]; int nwrite; if(argc <= 1) { printf("Usage: ./fifo_write string\n"); exit(1); } sscanf(argv[1], "%s", buff); /* 以只写阻塞方式打开 FIFO 管道 */ fd = open(MYFIFO, O_WRONLY); if (fd == -1) { printf("Open fifo file error\n"); exit(1); } /*向管道中写入字符串*/ if ((nwrite = write(fd, buff, MAX_BUFFER_SIZE)) > 0) { printf("Write '%s' to FIFO\n", buff); } close(fd); exit(0);}

 

  • 以下是读管道程序:
#include 
#include
#include
#include
#include
#include
#include
#include
#define MYFIFO "/tmp/myfifo" /* 有名管道文件名*/#define MAX_BUFFER_SIZE PIPE_BUF /*定义在于 limits.h 中*/ int main(){ char buff[MAX_BUFFER_SIZE]; int fd; int nread; /* 判断有名管道是否已存在,若尚未创建,则以相应的权限创建*/ if (access(MYFIFO, F_OK) == -1) { if ((mkfifo(MYFIFO, 0666) < 0) && (errno != EEXIST)) { printf("Cannot create fifo file\n"); exit(1); } } /* 以只读阻塞方式打开有名管道 */ fd = open(MYFIFO, O_RDONLY); if (fd == -1) { printf("Open fifo file error\n"); exit(1); } while (1) { memset(buff, 0, sizeof(buff)); if ((nread = read(fd, buff, MAX_BUFFER_SIZE)) > 0) { printf("Read '%s' from FIFO\n", buff); } } close(fd); exit(0);}

  

 二、消息队列

1. 消息队列概述

  • 顾名思义,消息队列就是一些消息的列表。用户可以从消息队列中添加消息和读取消息等。从这点上看, 消息队列具有一定的 FIFO 特性,但是它可以实现消息的随机查询,比 FIFO 具有更大的优势。同时,这些消息又是存在于内核中的,由“队列 ID”来标识。

2. 消息队列的应用

(1)函数说明

消息队列的实现包括创建或打开消息队列、添加消息、读取消息和控制消息队列这 4 种操作。其中创建 或打开消息队列使用的函数是 msgget(),这里创建的消息队列的数量会受到系统消息队列数量的限制; 添加消息使用的函数是 msgsnd()函数,它把消息添加到已打开的消息队列末尾;读取消息使用的函数是 msgrcv(),它把消息从消息队列中取走,与 FIFO 不同的是,这里可以指定取走某一条消息;最后控制消息队列使用的函数是 msgctl(),它可以完成多项功能。

(2)函数格式

  • msgget()函数的语法要点。

                                             

  •  msgsnd()函数的语法要点。

                                             

                                              

 

3.使用实例

  • 消息队列发送端的代码:
#include 
#include
#include
#include
#include
#include
#include
#define BUFFER_SIZE 512struct message{ long msg_type; char msg_text[BUFFER_SIZE];};int main(){ int qid; key_t key; struct message msg; /*根据不同的路径和关键字产生标准的 key*/ if ((key = ftok(".", 'a')) == -1) { perror("ftok"); exit(1); } /*创建消息队列*/ if ((qid = msgget(key, IPC_CREAT|0666)) == -1) { perror("msgget"); exit(1); } printf("Open queue %d\n",qid); while(1) { printf("Enter some message to the queue:"); if ((fgets(msg.msg_text, BUFFER_SIZE, stdin)) == NULL) { puts("no message"); exit(1); } msg.msg_type = getpid(); /*添加消息到消息队列*/ if ((msgsnd(qid, &msg, strlen(msg.msg_text), 0)) < 0) { perror("message posted"); exit(1); } if (strncmp(msg.msg_text, "quit", 4) == 0) { break; } } exit(0);}
  • 以下是消息队列接收端
#include 
#include
#include
#include
#include
#include
#include
#define BUFFER_SIZE 512 struct message { long msg_type; char msg_text[BUFFER_SIZE]; }; int main() { int qid; key_t key; struct message msg; /*根据不同的路径和关键字产生标准的 key*/ if ((key = ftok(".", 'a')) == -1) { perror("ftok"); exit(1); } /*创建消息队列*/ if ((qid = msgget(key, IPC_CREAT|0666)) == -1) { perror("msgget"); exit(1); } printf("Open queue %d\n", qid); do { /*读取消息队列*/ memset(msg.msg_text, 0, BUFFER_SIZE); if (msgrcv(qid, (void*)&msg, BUFFER_SIZE, 0, 0) < 0) { perror("msgrcv"); exit(1); } printf("The message from process %d : %s", msg.msg_type, msg.msg_text); } while(strncmp(msg.msg_text, "quit", 4)); /*从系统内核中移走消息队列 */ if ((msgctl(qid, IPC_RMID, NULL)) < 0) { perror("msgctl"); exit(1); } exit(0);
server.c
#include 
#include
#include
#include
#include
#include
#include
#include
#define PORT 4321#define BUFFER_SIZE 1024#define MAX_QUE_CONN_NM 5int main(){ struct sockaddr_in server_sockaddr,client_sockaddr; int sin_size,recvbytes; int sockfd, client_fd; char buf[BUFFER_SIZE];/*创建socket套接字接口*/ sockfd = socket(AF_INET,SOCK_STREAM,0);/*设置本地地址的相关参数*/ server_sockaddr.sin_family = AF_INET; server_sockaddr.sin_port = htons(PORT); server_sockaddr.sin_addr.s_addr = INADDR_ANY; bzero(&(server_sockaddr.sin_zero),8);/*允许重复使用本地地址与套接字进行绑定*/ int i = 1; setsockopt(sockfd, SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i));/*绑定套接字和本地计算机*/ bind(sockfd,(struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr));/*监听客户端连接*/ listen(sockfd, MAX_QUE_CONN_NM);/*接收客户端的连接请求*/ client_fd = accept(sockfd,(struct sockaddr *)&client_sockaddr,&sin_size);/*接收客户端的发送*/ recvbytes = recv(client_fd, buf, BUFFER_SIZE, 0);/*关闭窗口*/ close(sockfd); exit(0);}
 

 

 

转载于:https://www.cnblogs.com/leeRan/p/6935261.html

你可能感兴趣的文章
把word文档中的所有图片导出
查看>>
ubuntu 18.04取消自动锁屏以及设置键盘快捷锁屏
查看>>
arcgis api 4.x for js 结合 Echarts4 实现散点图效果(附源码下载)
查看>>
YTU 2625: B 构造函数和析构函数
查看>>
apache自带压力测试工具ab的使用及解析
查看>>
加固linux
查看>>
Hyper-V虚拟机上安装一个图形界面的Linux系统
查看>>
【Crash Course Psychology】2. Research & Experimentation笔记
查看>>
关于 linux 的 limit 的设置
查看>>
MTK笔记
查看>>
激活office 365 的启动文件
查看>>
【题解】 bzoj1597: [Usaco2008 Mar]土地购买 (动态规划+斜率优化)
查看>>
fat32转ntfs ,Win7系统提示对于目标文件系统文件过大解决教程
查看>>
shell cat 合并文件,合并数据库sql文件
查看>>
构建自己的项目管理方案
查看>>
利用pca分析fmri的生理噪声
查看>>
div水平居中且垂直居中
查看>>
epoll使用具体解释(精髓)
查看>>
AndroidArchitecture
查看>>
安装Endnote X6,但Word插件显示的总是Endnote Web"解决办法
查看>>