一、基础知识。

1:进程通信基础(interProcess Communication, IPC):管道,FIFO(命名管道),XSI IPC,POSIX 信号量。

2:管道。

  1,缺陷。

    1)部分系统支持全双工(不确定linux)

    2)管道只能在具有公共祖先的两个进程之间使用。

  2,相关函数。

  3,协同进程:一个过滤程序既产生某个过滤程序的输入,又读取该过滤程序的输出。

3:FIFO。

  1,作用:能够使 不相关的进程 进行通信。

  2,一些注意点。

    1)FIFO路径名存在于文件系统中。

  3,一些用途。

    1)shell命令使用FIFO将数据从一条管道传送到另外一条。无需创建中间文件。

    2)C/S模式中,FIFO用作汇聚点,在客户进程和服务器进程之间传递数据。

4:XSI IPC。

  1,有三种:消息队列,信号量,共享储存器。

  2,使用 非负整数 的标识符。数据类型为: key_t <sys/types.h>

  3,有多种方法使 客户进程 和服务器进程 在同一IPC结构上汇聚。

    1)服务器进程指定键IPC_PROVATE创建新IPC结构,并将标识符存放在某处,让客户进程取用。

    2)在公共头文件中定义一个 两个进程 都认可的键。

    3)两个进程 认可一个路径名和项目ID使用ftok函数将两个值变成一个KEY。

  4,基本问题。

    1)IPC结构在系统范围内起作用,没有引用计数。

    2)IPC结构在文件系统中没有名字。

    3)IPC不能使用文件描述符,所以不能对它们使用多路转接IO函数。

  5,消息队列:消息的链接表。

  6,信号量:一个计数器。用于为多个进程提供对共享数据对象的访问。

    1)信号量通常在内核中实现。且减1操作为原子操作。

    2)进程终止时,内核会自动检测信号量,并进行调整。

    3)互斥量比信号量快很多。但如果可能尽量使用信号量。因为信号量的心痛支持度较高,而且复杂性更低。

  7,共享存储:最快的IPC。

    1)信号量可用于同步共享储存访问。

5:POSIX 信号量。

  1,相对XSI优点。

    1)更高性能。

    2)使用更简单:没有信号量集,部分操作统一化。

    3)信号量删除表现的更完美:直到最后一次使用后才释放。

  2,拥有两种性是:命名的和未命名的。差异:创建和销毁的形式上。

  3,为增加移植性,信号量命名应该有一定规则:

    1)第一个字符为 斜杠 / 。

    2)名字不包含其他斜杠以避免实现定义的行为。

    3)信号量名最大长度由实现定义。

  4,P470 客户进程-服务器进程属性。

二、相关函数。

1:管道。

 创建管道。
  int pipe( int fd[] );
  // 1 fd[0]为读 fd[1]为写。fd[1]的输出是fd[0]的输入。
创建一个管道,fork一个子进程,关闭未使用的管道端,执行一个shell命令,等待命令终止。
  // !!!需要进一步了解者两个函数原理和使用机制!!!
  FILE *popen( cosnt char *cmdstring, const char *type );  // fork --> exec and cmd --> return a ptr of IO.
  int pclose( FILE *fp );
  // 适用于简单的过滤器程序

 2:FIFO:命名管道。

#include <sys/stat.h>
创建FIFO
  int mkfifo( const char *path, mode_t mode );
  int mkfifoat( int fd, const char *path, mode_t mode );
  // 1 一般情况下,都是阻塞到读写开始为止。但设置非阻塞时,会立即返回-1,errno设置ENXIO。

 3:XSI IPC

 通过路径名+项目ID产生一个KEY。
  key_t ftok( const char *path, int id );
  // 1 参数path必须引用现有文件,参数id只使用低8位。
ipc_perm 权限和所有者.
  struct ipc_perm
  {
    uid_t uid; // owner's effective user id.
    gid_t gid; // owner's effective group id.
    uid_t cuid; // creator's effective user id.
    gid_t cgid; // creator's effective group id.
    mode_t mode; // access modes
  } // 此为最小结构。具体实现 可添加成员
消息队列的信息结构 msqid_ds。
  struct msqid_ds
  {
    struct ipc_perm msg_perm; // see section.
    msgqnum_t msg_qnum; // # of messages on queue.
    msglen_t msg_qbytes; // max # of bytes on queue.
    pid_t msg_lspid; // pid of last msgsnd()
    pid_t msg_lrpid; // pid of last msgrcv()
    time_t msg_stime; // last-msgsnd() time
    time_t msg_rtime; // last-msgrcv() time
    time_t msg_ctime; // last-change time
  }
打开/创建 一个队列。
  int msgget( key_t key, int flag );
对 队列 执行多种操作。
  int msgctl( int msqid, int cmd, struct msqid_ds *buf );
  // 1 参数cmd:IPC_STAT, IPC_SET, IPC_RMID
将数据放到消息队列中。
  int msgsnd( int msqid, cosnt void *ptr, size_t nbytes, int flag );
  // 1 参数ptr:指向mymesg结构。
从队列取消息。
  ssize_t megrcv( int msqid, void *ptr, size_t nbytes, long type, int flag );
  // 1 参数type:>0时,以非 先进先出 的次序 获取消息。
获取一个信号量。
  int semget( key_t key, int nsems, int flag );
多种信号量操作。
  int semctl( int semid, int semnum, int cmd, .../* union semun arg */ );
  // 1 参数cmd:IPC_STAT,IPC_SET,IPC_RMID,GETVAL...
自动执行信号量集合上的操作数组。
  int semop( int semid, struct sembuf semoparray[], size_t nops ); // 具有原子性,或者执行所有,或者全部不执行。
  struct sembuf
  {
    unsigned short sum_num; // member # in set (0, 1, ..., nsems-1)
    short sem_op; // operation(negative, 0, or pasitive )
    short sem_flg; // IPC_NOWAIT, SEM_UNDO
  }
内核为每个共享储存段维护一个结构。
  struct shmid_ds
  {
    struct ipc_perm shm_perm; // see section
    size_t shm_segsz; // size of segment in bytes
    pid_t shm_lpid; // pid of last shmop
    pid_t shm_cpid; // pid of creator
    shmatt_t shm_nattch; // number of current attaches
    time_t shm_atime; // last-attach time
    time_t shm_dtime; // last-detach time
    time_t shm_ctime; // last-change time
    ...
  }
获得一个共享储存标示符。
  int shmget( key_t key, size_t size, int flag );
  // 1 参数size:字节为单位。通常为系统页长的整倍数。
对共享存储 执行多种操作。
  int shmctl( int shmid, int cmd, struct shmid_ds *buf );
  // 1 参数cmd:IPC_STAT,IPC_SET,IPC_RMID,SHM_LOCK,SHM_UNLOCK
将共享存储连接到进程中。
  void shmat( int shmid, cosnt void *addr, int flag );
进程和共享存储的分离操作(不删除共享存储)。
  int shmdt( const void *addr );

4:POSIX 信号量。

 创建信号量 / 使用现有信号量。
  sem_t sem_open( const char *name, int oflag, mode_t mode, unsinged int value );
释放信号量相关资源。
  int sem_close( sem_t *sem );
销毁一个命名信号量。
  int sem_unlink( const char *name ); // 当最后一个引用关闭时 才销毁。
实现信号量减一操作。
  int sem_trywait( sem_t *sem );
  int sem_wait( sem_t *sem );
  int sem_timedwait( sem_t *sem, const struct timespec *restrict tsptr );
  // 1 资源为0时,发生阻塞。>0,减一
信号量+
  int sem_post( sem_t *sem );
创建/销毁 一个未命名信号量。
  int sem_init( sem_t *sem, int pshared, unsigned int value );
  int sem_destroy( sem_t *sem );
检索信号量值。
  int sem_getvalue( sem_t *restrict sem, int *restrict valp );
  // 1 除非使用额外的同步机制来避免竞争,否则此函数只能用于调试

三、

linux学习笔记之进程间通信的更多相关文章

  1. Linux 学习笔记

    Linux学习笔记 请切换web视图查看,表格比较大,方法:视图>>web板式视图 博客园不能粘贴图片吗 http://wenku.baidu.com/view/bda1c3067fd53 ...

  2. linux学习笔记2-linux的常用命令

    第一篇博客:linux学习笔记1-ubuntu的安装与基本设置 之中,已经介绍了如何安装linux操作系统,以及一些基本的设置修改. 本篇博客主要介绍linux中的一些常用的终端命令 ======== ...

  3. Linux学习笔记(一)2015.4.13

    研究生由单片机转Linux学习 首先安装VMware虚拟机,用的是VMware 10.0 在VMware 10.0上安装视频上推荐的Red Hat Linux 5 安装后正式进入Linux学习 笔记1 ...

  4. 20160127 linux 学习笔记

    Linux学习笔记第一天 Linux基本介绍 Linux的起源和发展: 简单说linux是一种操作系统,可以安装在包括服务器.个人电脑,乃至PDA.手机.打印机等各类设备中. 起源: Linux起源于 ...

  5. linux —— 学习笔记(汇总)

    笔记目录:一.系统知识 和 基本概念                    二.常用操作                   三.系统管理(内存.设备.服务等管理)                   ...

  6. Linux学习笔记-林耐斯Notes-Linux就该这么学

    Linux学习笔记... 参考的优秀Linux网站: http://www.w3cschool.cn/linux/ http://www.linuxeye.com/ http://linux.vbir ...

  7. Linux~学习笔记目录索引

    回到占占推荐博客索引 本篇文章是对自己学习Linux及在它的环境下部署工具的一个总结,以方便自己查阅,也给他人一个帮助,本文章同时会不断的更新,欢迎大家订阅! 本目录包括的内容会包括linux基础命令 ...

  8. deepin linux学习笔记(四)进不去图形界面怎么办?

    目录 deepin linux学习笔记(四)进不去图形界面怎么办? 前言 更换成lxde桌面 进不去图形界面怎么办? 总结 deepin linux学习笔记(四)进不去图形界面怎么办? 前言 生命不息 ...

  9. deepin linux 学习笔记(二)——文本编辑器

    目录 deepin linux 学习笔记(二)--文本编辑器 前言 nano 小巧的命令行编辑器 通用 编辑 定位 排版 配置 vim 思路独特的超级编辑器 命令模式 插入模式 底线模式(末行模式) ...

随机推荐

  1. grep;egrep;fgrep

    -1 使用场景:搜索定位内容并输出(所在行) -2 三者区别: --1 grep  默认支持普通正则 --2 egrep 默认支持扩展正则 等同于 grep -E --3 fgrep 速度最快,不支持 ...

  2. python中__init__.py文件的作用

    问题 在执行models.py时,报ImportError:No module named transwarp.db的错误,但明明transwarp下就有db.py文件,路径也没有错误.真是想不通.后 ...

  3. Wireless Network(POJ 2236)

    Wireless Network Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 20724   Accepted: 871 ...

  4. ES6新特性-------解构、参数、模块和记号(续)

    六.解构 解构提供了一个方便的地从对象或数组中提取数据的方法,请看下面的例子: //ES6 let [x,y]=[1,2];//x=1,y=2 //ES5 var arr=[1,2]; var x=a ...

  5. html 标记语言

    HTML    html标记语言        网页            <html></html>        可见页面内容            <body> ...

  6. Java 正则提取数字串

    例如:有一个字符串:"数量最低2000份",将其中的2000数字提取出来. String arg0 = "数量最低2000份"; Pattern p = Pat ...

  7. QT---线程间通信(要先编译libqt-mt.so?)

    在 Qt 系统中,运行着一个GUI 主事件线程,这个主线程从窗口系统中获取事件,并将它们分发到各个组件去处理.在 QThread 类中有一种从非主事件线程中将事件提交给一个对象的方法,也就是 QThr ...

  8. XML文档形式&JAVA抽象类和接口的区别&拦截器过滤器区别

    XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式? a: 两种形式 dtd schemab: 本质区别:schema本身是xml的,可以被XML解析器解析(这也是从DTD上发 ...

  9. 百度地图LV1.5实践项目开发工具类bmap.util.jsV1.2

    /** * 百度地图使用工具类-v1.5 * * @author boonya * @date 2013-7-7 * @address Chengdu,Sichuan,China * @email b ...

  10. 剑指offer-面试题22.栈的压入,弹出序列

    题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第 二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等. 例如序列1.2.3.4.5是某栈的压栈序列,序列4.5.3.2.1 是该压栈 ...