11、UC IPC进程间通信

自作多情 提交于 2019-12-15 00:59:04

耦合性 代码的耦合性越低越好
内聚性 内聚性越强越好

一、IPC进程间通讯
system v IPC
使用命令ipcs可以查看system v IPC的对象
第一步:获取一个键值(唯一的值)
如果获取一个键值?
使用ftok(3)获取一个键值

#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
功能:转换pathname和proj_id为一个key值
参数:
     pathname:指定文件的名字
     proj_id:一个整数,这个整数的低8位不能为0
返回值:
       -1      错误        errno被设置
       成功    key值被返回

举例验证,使用ftok(3)获取一个键值
代码参见 ftok.c

如果文件名字和数字完全一样,多次运行进程产生的key值,完全一样。

第二步:通过键值获取一块内存,将这块内存id返回
第三步:通过内存的id操作这块内存

包含以下三个方面:
1、消息队列
通过键值获取一块内存,将这块内存id返回。
需要使用到msgget(2)获取内核内存的id

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
功能:获取一个消息队列的id
参数:
     key:ftok(3)获取到的键值
     msgflg:
            IPC_CREAT
            IPC_EXCL
     mode:指定了消息队列的权限
返回值:
        -1       失败      errno被设置
        成功    返回消息队列的id

举例验证,通过键值获取消息队列的id
代码参见 msgget.c

向消息队列中发送消息,使用msgsnd(2)

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
功能:向消息队列发送消息
参数:
     msqid:指定了要操作的消息队列的id
     msgp:指向struct msgbuf类型的变量的指针
     msgsz:是mtext的长度
     msgflg:
           IPC_NOWAIT:在空间不够的情况下,非阻塞等待,立即返回错误
                    0:空间不够的情况下,等待空间充足才能解除阻塞
返回值:
       -1      错误      errno被设置
        0      成功

举例 讲一个消息放入到消息队列中。代码参见processA.c

ssize_t msgrcv(int msqid, void *msgp, size_t magsz, long msgtyp, int msgflg);
功能:从消息队列中获取消息
参数:
     msqid:指定了消息队列的id
     msgp:指向了获取到的消息
     magsz:是mtext的长度
     msgtyp:消息的类型
     msgflg:
            IPC_NOWAIT:如果消息队列中没有消息,立即返回。
                     0:如果消息队列中没有消息,阻塞等待
返回值:
        -1     错误     errno被设置
        获取到的消息体的字节数

举例编写代码实现从消息队列中,获取消息,并将消息输出到显示器
代码参见 processB.c

补充:

struct msgbuf{
    long mtype;       /* message type, must be > 0 */
    char mtext[1];    /* message data */
}

2、共享内存
根据键值获取共享内存的id,如何获取?
使用shmget(2)获取共享内存id

#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
功能:
参数:
     key:ftok(3)返回的key值
     size:指定了共享内存的尺寸
     shmflg:
            IPC_CREAT:指定创建共享内存段
            IPC_EXCL:
       mode:
返回值:
       -1      错误     errno被设置
       返回共享内存段的id

举例,创建共享内存段。代码参见shm.c

将共享内存映射到进程的虚拟地址空间,使用shmat(2)

#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:将共享内存绑定到进程的地址空间
参数:
     shmid:共享内存的id
     shmaddr:指定了进程绑定共享内存的地址。指定为NULL,由系统做选择
     shmflg:
            SHM_RDONLY:共享内存段只读
返回值:
       返回和共享内存绑定的地址
       (void *)-1      错误     errno被设置
int shmdt(const void *shmaddr);
功能:解除和共享内存段的绑定
参数:
     shmaddr:指定了要解除的共享内存段在进程中的地址
返回值:
       0        成功
       -1       失败     errno被设置

举例使用共享内存完成进程间的通讯。 代码参见shmA.c shmB.c

3、信号量集

补充:
ipc 通讯对象的操作
命令
ipcs
ipcrm用来从内核中移除ipc通讯对象

作业的问题:
mycp的实现
代码参见mycp.c

二、网络基础知识
所有的网络编程都是基于客户端(client)和服务器(server)的架构
什么是协议?
协议就是规则。

水晶头的大小和网卡预留的水晶头插口需要 遵循一种协议,电气协议。

网帧:
以太网卡、令牌环网卡
对网帧做了不同的定义。逻辑层

网络通讯采用的协议是TCP/IP协议族
OSI七层模型
TCP/IP协议分为四层或者五层
应用层、传输层、网络层、链路层
应用层、传输层、网络层、链路层、物理层

物理层规定了网络中的电气协议
链路层规定了帧的格式

网络地址、

ip地址                  32位
网卡的MAC地址   6字节    48位   (网卡的)物理地址

如何查看一台机器的ip地址和物理地址

ifconfig

端口号

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!