30,UC(09)

 

回顾:
  信号:信号集、信号屏蔽sigprocmask()、sigaction()是signal()增强版,如果需要对信号本身有更多的了解,可以使用sigaction()。结构sigaction中配置sa_flags为SA_SIGINFO,并使用sa_sigaction作为处理函数的指针。
  siqueue()和计时器
  IPC: IPC原理 两个进程通过一个媒介 完成数据交互。
  管道: 有名管道 无名管道
   用mkfifo创建管道文件 进行通信。
  无名管道主要用于fork()创建的父子进程之间的通信。
今天:
  无名管道 用pipe()提供内核的管道文件和读写通道。
  XSI IPC(重点)
   共享内存、消息队列和信号量集 都属于XSI IPC规范,因此在用法上有很多共同点。
   共享内存的媒介是 一块内核管理的内存,多个进程映射到这块内存上读写数据,完成数据交互。共享内存 效率高,但多进程同时写入时,数据会被互相 覆盖。
   XSI的共同点:
    1 共享内存、消息队列和信号量集都是Linux/Unix的内核对象,重启机器不会消失。程序创建了XSI IPC之后,如果不再使用,一定要在程序中删除。
    2 使用方式的共同点
     2.1 创建/获取 都需要一个外部key和内部ID。用key可以得到内部ID,内部ID对应 内核中的IPC结构。
     2.2 key的生成有三种方式:
     宏IPC_PRIVATE 直接做key,这种方式基本不用,因为这种方式只能创建不能获取。
     定义一个通用的头文件,把所有的key定义在头文件中,key其实就是一个整数。
     函数ftok()负责生成key:
    key_t key = ftok(path,projectid);
    path 是一个必须真实存在的路径,projectid随便给一个恩就行,不要重复,范围0-255.
    如果path和projectid相同,key的值就相同。
    2.3 用key创建/获取ID
     XSI IPC都有一个 xxxget() 获取/创建 内部ID。
      int shmid = shmget();
      int msgid = msgget();
    2.4 创建IPC结构时,都需要提供一个参数flags,一般为
    IPC_CREAT|IPC_EXCL|0660 (和O_ 类似)
    IPC_EXCL 如果结构已经存在,返回-1 出错。
    2.5 对IPC结构都提供一个 操作函数xxxctl(),包含:
     IPC_STAT : 获取IPC结构的相关属性
     IPC_SET  : 修改IPC结构的相关属性(能改的很少)
     IPC_RMID : 按照ID 删除IPC结构
     比如:shmctl()  msgctl()
   
   IPC相关命令:
    ipcs 查看当前内核中的ipc结构
     -a 所有
     -m 共享内存
     -q 消息队列
     -s 信号量集
    ipcrm 删除当前内核中的ipc结构
     ipcrm -m ID 按ID删除
      
   共享内存的使用步骤:
    1 使用ftok()创建一个外部key(包含头文件也行)。
    2 使用shmget()创建/获取共享内存的内部ID。
    3 使用shmat()挂接共享内存(映射),返回 首地址
    4 正常使用 首地址(或读或写)
    5 使用shmdt()脱接共享内部(解除映射)
    6 如果所有进程都不再使用,使用shmctl()删除共享内存
   
  注:ftok的参数projectid 必须非0.

   当使用删除命令/函数 删除共享内存时,不确保立即删除。只是给 共享内存做一个删除标记,当 挂接进程数为0 才能真正删除。nattch 就是挂接进程数。

   shmctl()包括: 查询共享内存的属性、修改共享内存的属性、删除共享内存。
   XSI IPC应用最多的是 消息队列。
   可以把数据 封入消息中,然后 再把消息 放入队列中。内核创建和管理队列,进程把 数据封入消息 在放入队列或从队列中取出消息。
   消息队列的使用步骤:
   1 使用ftok() 得到key。
   2 使用msgget()用key 创建/获取 内部ID。
   3 使用函数 msgsnd() msgrcv()放入或取出消息(队列中)
   4 如果不再使用消息队列,msgctl()删除队列。
 
  消息分为有类型消息和无类型消息,无类型消息可以是任意类型的数据,比如:字符串、整数、浮点。
  有类型消息,类型是预先设定的结构体,而且结构:
   struct 任意名字{
     long mtype; //第一个成员必须 消息的类型
     char msg[100];//第二个成员 随意 消息的数据
   };
   消息类型可以让 不同的进程 拿到自己的消息,而不用考虑谁先谁后。消息类型必须是大于0的整数,0代表 任意类型。
  msgsnd(msgid,&msg,sizeof(msg),0/*IPC_NOWAIT*/)
   0 代表如果队列满了阻塞
   IPC_NOWAIT代表如果队列满了直接返回错误
  注:在发送时,计算sizeof 不包括消息类型(包括了也没错)
  msgrcv(msgid,&msg,sizeof(msg),msgtype,
0/*IPC_NOWAIT*/)
  注:发送时size如果不包括消息类型,接收时也不要包括
  msgtype 设定接收消息的类型,包括:
   == 0  接收任意类型的消息,典型的先入先出
    > 0  接收对应类型的消息
    < 0  接收 小于等于 msgtype绝对值的 最小类型消息
   (类型 从小到大)

 作业: 为综合案例 模拟实现银行ATM功能
   1 思考:银行ATM的基本功能,界面
   2 复习以下知识点:
    消息队列、多进程、信号signal()、文件的基本操作

 安排: 
   1 助教老师 系统分析
   2 自己思考/动手,如有问题 多问。
   3 周四上午 讲师讲解
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值