三种IPC这就是所谓的XSI IPC,每间:

  • 消息队列
  • 信号量
  • 共享存储器
以下分别介绍三种IPC的使用方法。

1、消息队列
消息队列是消息的链接表,具有例如以下函数接口:
  • msgget:创建一个新队列或打开一个现存的队列。
  • msgsnd:将消息加入到队列尾端。
  • msgrcv:从队列中取消息。
我们能够自行定义一个表示消息的结构体,它由类型字段和实际数据组成:
struct mest_t {
long type; // 消息类型
char text[512]; // 消息内容
};

有了消息类型。当我们用msgrcv函数取消息时,就不一定要以先进先出的顺序,而是能够依据消息类型取消息了。以下是一段简单的測试代码:
#include <stdio.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h> struct mest_t {
long type;
char text[512];
}; int main(void)
{
pid_t pid;
int mq_id;
struct mest_t msg; /* IPC_PRIVATE用于创建一个新队列
* 设置了IPC_EXCL而且设置了IPC_CREAT。当文件存在时返回错误
*/
mq_id = msgget(IPC_PRIVATE, IPC_CREAT | IPC_EXCL);
if (mq_id == EEXIST)
return -1; /* 返回EEXIST表示IPC已存在 */ if ((pid = fork()) < 0)
return -1;
else if (pid == 0)
{
/* 子进程 */
msg.type = 123; /* 消息类型 */
strcpy(msg.text, "Hello world!"); /* 消息内容 */ /* 非堵塞方式将消息放入消息队列
* 队列已满则返回EAGAIN
*/
while (msgsnd(mq_id, (long *)&msg, 512, IPC_NOWAIT) == EAGAIN)
sleep(1);
}
else
{
/* 非堵塞方式从队列中取消息
* 假设没有指定类型的消息。函数返回-1,errno设置为ENOMSG
*/
while (msgrcv(mq_id, (long *)&msg, 512, 123, IPC_NOWAIT) == -1)
{
if (errno == ENOMSG)
{
printf("There is no this type message!\n");
sleep(1);
}
} printf("%s\n", msg.text);
} return 0;
}

当父进程须要取的消息类型和子进程发送的消息类型同样时。执行结果例如以下:


父进程可以非常快接收到子进程发送到消息队列中的消息。

可是改动msgrcv的消息类型參数后,执行结果例如以下:



父进程得不到想要的消息,一直打印错误信息。

2、信号量
信号量是一个计数器。用于多进程对共享数据对象的訪问。步骤例如以下:
  • 測试控制该资源的信号量。
  • 若此信号量的值为正。则进程能够使用该资源。进程将信号量值减1,表示它使用了一个资源单位。
  • 若此信号量的值为0。则进程进入休眠状态,直至信号量大于0。进程被唤醒后。它返回至第一步。
当进程不再使用由一个信号量控制的共享资源时,该信号量值增1。假设有进程正在休眠等待此信号量,则唤醒它们。

3、共享存储
共享存储同意多个进程共享一块给定的存储区。是最快的一种IPC。測试代码例如以下:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/shm.h> #define SHM_SIZE 100
#define SHM_MODE (SHM_W | SHM_R | IPC_CREAT) int main()
{
int shmid;
char *shmptr;
pid_t pid; /* 获得共享存储标识符 */
if ((shmid = shmget(IPC_PRIVATE, SHM_SIZE, SHM_MODE)) < 0)
return -1; if ((pid = fork()) < 0)
return -1;
else if (pid == 0)
{
shmptr = shmat(shmid, 0, 0); /* 參数2为0表示由内核分配共享空间 */
printf("Child attached shared memory is : %lx\n", (unsigned long)shmptr);
shmdt(shmptr); /* 使进程脱离该共享空间 */
}
else
{
waitpid(pid, NULL, 0); shmptr = shmat(shmid, 0, 0);
printf("Parent attached shared memory is : %lx\n", (unsigned long)shmptr);
shmdt(shmptr); shmctl(shmid, IPC_RMID, 0); /* 删除该共享存储段 */
} return 0;
}

执行结果:



从上面的实验结果能够看出,父、子进程共享了同一个存储段。

有一点须要注意,shmdt函数仅仅是让进程脱离该共享存储段,但该存储段依旧存在而且shmid依旧有效。它是与shmat相相应的。而还有一个函数shmctl使用IPC_RMID參数时才是真正删除该共享段。


共享存储段和存储映射I/O中的mmap函数很相似,它们之间的差别是:mmap映射的存储段是与文件相关联的,XSI共享存储段则并无这样的关联。

参考:
《unix编程环境》 P415-P432.

【Linux计划】XSI IPC的更多相关文章

  1. linux进程间通信-XSI IPC

    一 什么是XSI IPC     有三种 IPC我们称作XSI IPC,即消息队列.信号量以及共享存储器(共享内存),它们之间有很多相似之处. 二 标识符和键     每个内核中的 IPC结构(消息队 ...

  2. 进程间通信之XSI IPC

    XSI IPC源自于系统V的IPC功能. 有三种IPC我们称作XSI IPC,即消息队列.信号量以及共享存储器,它们之间有很多相似之处. 1.标识符和键 每个内核中的IPC结构(消息队列.信号量或共享 ...

  3. 进程间通信——XSI IPC之消息队列

    进程间通信XSI IPC有3种:消息队列.共享内存.信号量.它们之间有很多相似之处,但也有各自的特殊的地方.消息队列作为其中比较简单的一种,它会有些什么东西呢,来一起探讨探讨.. 消息队列结构 消息队 ...

  4. Linux ns 5. IPC Namespace 详解

    文章目录 1. 简介 2. 源码分析 2.1 copy_ipcs() 2.2 ipcget() 2.3 ipc_check_perms() 2.4 相关系统调用 参考文档: 1. 简介 进程间通讯的机 ...

  5. linux下六大IPC机制【转】

    转自http://blog.sina.com.cn/s/blog_587c016a0100nfeq.html linux下进程间通信IPC的几种主要手段简介: 管道(Pipe)及有名管道(named ...

  6. Linux计划任务Crontab实例详解教程

    说明:Crontab是Linux系统中在固定时间执行某一个程序的工具,类似于Windows系统中的任务计划程序 下面通过详细实例来说明在Linux系统中如何使用Crontab 操作系统:CentOS ...

  7. Linux计划任务(转载)

    Linux计划任务(转载) Linux的计划任务是系统管理方面的一个重要内容,是系统自动完成工作的一种实现方式,正因为有了计划任务,我们才可以完全实现系统管理的脚本化和自动化. 关于计划任务,Linu ...

  8. Linux 计划任务总结

    今天项目用到了,Linux计划任务,从网上找了基本blog看了,总结了下. Linux 下的计划任务有atd和crond两种计划任务.atd服务使用的at命令只能执行一次,而crond服务使用的cro ...

  9. Linux. 计划任务 时间格式

    Linux. 计划任务 时间格式 在linux中执行指令:cat /etc/crontab 结果,如下图所示: 结果一目了然,不多说. 如有问题,欢迎纠正!!! 如有转载,请标明源处:https:// ...

随机推荐

  1. 用Eclipse替代Keil&IAR来开发ARM应用(升级版)

    Eclipse GNU ARM Plugin 2014/7/16 作者 kiya 几个月前写了一篇<),想自己丰衣足食的参考我的上一篇文章,以及GNU ARM的官网. 用Eclipse替代Kei ...

  2. js进阶 11-14 jquery如何实现元素的替换和遍历

    js进阶  11-14  jquery如何实现元素的替换和遍历 一.总结 一句话总结:替换:replaceAll() 与 replaceWith().遍历:each(). 1.replaceAll() ...

  3. Django表单上传

    任务描述:实现表单提交(上传文件) 1.项目目录: 2.源代码: regist.html <!DOCTYPE html> <html lang="en"> ...

  4. 小强的HTML5移动开发之路(47)——jquery mobile基本的页面框架

    一.单容器页面结构 <!DOCTYPE html> <html> <head> <title>Jquery mobile 基本页面框架</titl ...

  5. http://lists.mysql.com/mysql

    http://lists.mysql.com/mysql http://www.ehowstuff.com/how-to-fix-mysql-database-error-cant-create-da ...

  6. zzuli OJ 1128: 课程平均分

    Description 期末考试结束,班主任拿到了本班学生的成绩汇总表.由m行n列组成(本班共同拥有m名学生,本学期有n门课程),每行是一个同学的n门课程成绩,请编敲代码,计算并输出每门课的平均分.结 ...

  7. innodb_data_file_path参数误修改解决方法

    如果innodb_data_file_path参数被修改乱了,不知道原来值的大小,这样启动是会报错的.知道原来大小方法: 方法一:操作系统下ls -l看到原来大小,直接用ls -l显示的大小,复制即可 ...

  8. JQuery:cookie插件

    JQuery居然没有操作cookie相关的函数,搜了下官方有个cookie的插件. 简单使用方法: <head> <title>JQuery-Cookie插件</titl ...

  9. 小强的HTML5移动开发之路(24)—— PhoneGap Android开发环境搭建

    有关JDK及Android开发环境的搭建请看我前面的博文:http://blog.csdn.net/dawanganban/article/details/9748497 一.下载PhoneGap 下 ...

  10. 【noip模拟】德充符

    时间限制:2s 内存限制:512MB [题目描述] 申徒嘉和郑子产都是伯昏无人的学生,子产因为申徒嘉是残疾人,非常看不起他,于是想要刁难他. 子产给了申徒嘉 n个数 a1,a2...an. 现在他要求 ...