• 进程间通信


    管道:

    管道是一种两个进程间进行单向通信的机制。管道只能用于父子进程或兄弟进程间的通信,也就是说管道只能用于具有亲缘关系的进程间的通信。

    管道没有名字,管道的缓冲区大小是受限制的,它传递的是无格式的字节流,这就要求管道的输入方和输出方事先约好数据的格式。

    在创建管道时,系统为管道分配一个页面作为数据缓冲区,进行管道通信的两个进程通过读写这个缓冲区来进行通信。通过管道通信的两个进程,

    一个进程向管道写数据,另一个进程从管道的另一端读数据。写入的数据每次都添加在管道缓冲区的末尾,读数据的时候都是从缓冲区的头部读出数据。

    int pipe(int fd[2]);

    fd[0]描述管道读端,fd[1]用于管道写端。

    使用管道的流程:

    1)创建管道

    2)利用fork创建子进程

    3)控制管道流向

    4)从fd[1]向管道写数据  write(*write_fd,str,strlen(str));

    5)通过fd[0]从管道读信息  read(*read_fd,readbuffer,sizeof(readbuffer));

    管道进程的阻塞:进程试图读取空管道时,在有数据写入管道之前,进程将一直阻塞,同样,管道已满时,进程试图写管道时,在其他进程从管道中移走数据之前,写进程将一直阻塞。

    只有在管道读端存在时,向管道写入才有意义,否则会收到内核中的出错信号。

    向管道写入数据时不保证写入的原子性,管道缓冲区一有空闲区域,写进程就试图向其写入内容,若进程不读取管道中的内容,写进程就会一直阻塞。

    父子进程在运行时,他们的先后顺序不能得到保证,因此,为了保证父进程关闭读描述符,可向子进程加入sleep(2).

    消息队列:

    消息队列是一个链表,

    消息队列的操作:

    文件名到键值,键值

    #include <sys/types.h>
    #include <sys/ipc.h>
    key_t ftok (char*pathname, char proj);

    该函数不直接对消息队列操作,但在调用ipc(MSGGET,…)或msgget()来获得消息队列描述字前,往往要调用该函数

    int msgget(key_t key, int msgflg)

    参数key是一个键值,由ftok获得;msgflg参数是一些标志位。该调用返回与健值key相对应的消息队列描述字。

    在以下两种情况下,该调用将创建一个新的消息队列:

    • 如果没有消息队列与健值key相对应,并且msgflg中包含了IPC_CREAT标志位;
    • key参数为IPC_PRIVATE;

    参数msgflg可以为以下:IPC_CREAT、IPC_EXCL、IPC_NOWAIT或三者的或结果。

    参数key设置成常数IPC_PRIVATE并不意味着其他进程不能访问该消息队列,只意味着即将创建新的消息队列。

    int msgrcv(int msqid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg);
    该系统调用从msgid代表的消息队列中读取一个消息,并把消息存储在msgp指向的msgbuf结构中。

    msqid为消息队列描述字;消息返回后存储在msgp指向的地址,msgsz指定msgbuf的mtext成员的长度(即消息内容的长度),msgtyp为请求读取的消息类型;读消息标志msgflg可以为以下几个常值的或:

    • IPC_NOWAIT 如果没有满足条件的消息,调用立即返回,此时,errno=ENOMSG
    • IPC_EXCEPT 与msgtyp>0配合使用,返回队列中第一个类型不为msgtyp的消息
    • IPC_NOERROR 如果队列中满足条件的消息内容大于所请求的msgsz字节,则把该消息截断,截断部分将丢失。

    msgrcv手册中详细给出了消息类型取不同值时(>0; <0; =0),调用将返回消息队列中的哪个消息。

    msgrcv()解除阻塞的条件有三个:

    1. 消息队列中有了满足条件的消息;
    2. msqid代表的消息队列被删除;
    3. 调用msgrcv()的进程被信号中断;

    调用返回:成功返回读出消息的实际字节数,否则返回-1。

    3)int msgsnd(int msqid, struct msgbuf *msgp, int msgsz, int msgflg);
    向msgid代表的消息队列发送一个消息,即将发送的消息存储在msgp指向的msgbuf结构中,消息的大小由msgze指定。

    对发送消息来说,有意义的msgflg标志为IPC_NOWAIT,指明在消息队列没有足够空间容纳要发送的消息时,msgsnd是否等待。造成msgsnd()等待的条件有两种:

    • 当前消息的大小与当前消息队列中的字节数之和超过了消息队列的总容量;
    • 当前消息队列的消息数(单位"个")不小于消息队列的总容量(单位"字节数"),此时,虽然消息队列中的消息数目很多,但基本上都只有一个字节。

    msgsnd()解除阻塞的条件有三个:

    1. 不满足上述两个条件,即消息队列中有容纳该消息的空间;
    2. msqid代表的消息队列被删除;
    3. 调用msgsnd()的进程被信号中断;

    4)int msgctl(int msqid, int cmd, struct msqid_ds *buf);
    该系统调用对由msqid标识的消息队列执行cmd操作,共有三种cmd操作:IPC_STAT、IPC_SET 、IPC_RMID。

    1. IPC_STAT:该命令用来获取消息队列信息,返回的信息存贮在buf指向的msqid结构中;

    2. IPC_SET:该命令用来设置消息队列的属性,要设置的属性存储在buf指向的msqid结构中;可设置属性包括:msg_perm.uid、msg_perm.gid、msg_perm.mode以及msg_qbytes,同时,也影响msg_ctime成员。

    3.IPC_RMID:删除msqid标识的消息队列;

     信号:

  • 相关阅读:
    Rraspberry Pi 4B python3 安装opencv
    如何用arduion制作智能 垃圾桶
    MySQL(二)表结构的管理
    MySQL(一)基础操作
    vc++绘图基础
    网站签~
    (转)Oracle 知识日常积累
    利用反射判断bean属性不为空(null和空串)
    (转)Oracle 单字段拆分成多行
    svn 解决树冲突
  • 原文地址:https://www.cnblogs.com/sanshuiyijing/p/3473594.html
Copyright © 2020-2023  润新知