1. Unix IPC(InterProcess Communication)

同一主机的各个进程间的IPC:管道、FIFO、消息队列、信号量、共享存储器

不同主机上的各个进程间IPC:socket套接字
 

2. 管道

管道进行IPC有两个局限:
(1) 半双工,即数据只能在一个方向上流动
(2) 只能在具有公共祖先的进程之间使用。通常,一个管道由一个进程创建,然后该进程调用fork,此后 父子进程之间可以使用该管道
 
fstat函数对管道的每一端都返回一个FIFO类型的文件描述符,可以用S_ISFIFO宏来测试管道
 
通常是一个进程调用pipe函数创建管道,紧接着调用fork,这样就创建了从父进程到子进程的IPC通道
 
对于从父进程到子进程的管道,父进程关闭 管道的读端(fd[0])子进程关闭管道的写端(fd[1])
 
popen、pclose两个函数实现的操作是:创建一个管道,调用fork产生一个子进程,关闭管道的不使用端,执行一个shell以运行命令,最后等待命令终止
 
#include <stdio.h>

FILE* popen(const char* cmdstring, const char* type);
int pclose(FILE* fp);

函数popen先执行fork,然后调用exec以执行cmdstring,并且返回一个标准I/O文件指针

type为“r”表示可读,为“w”表示可写
 
简单实现一个popen:
 #include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/wait.h>
#include <fcntl.h> /* pointer to array allocated at run-time */
static pid_t* childpid = NULL; /* from our open_max() */
static int maxfd; FILE* my_popen(const char* cmdstring, const char* type)
{
int pfd[];
pid_t pid; /* only allow type = "r" or "w" */
if ((type[] != 'r' && type[] != 'w') || type[] != ) {
errno = EINVAL;
return NULL;
}
childpid = (pid_t*)calloc(maxfd, sizeof(pid_t));
if (childpid == NULL) {
return NULL;
}
} if (pipe(pfd) < ) {
return NULL;
} if ((pid = fork()) < ) {
return NULL;
} else if (pid == ) { /* child */
if (*type == 'r') {
close(pfd[]);
if (pfd[] != STDOUT_FILENO) {
dup2(pfd[], STDOUT_FILENO);
close(pfd[]);
}
} else {
close(pfd[]);
if (pfd[] != STDIN_FILENO) {
dup2(pfd[], STDIN_FILENO);
close(pfd[]);
}
} /* close all fds in childpid[] */
for (int i = ; i < maxfd; ++i) {
if (childpid[i] > ) {
close(i);
}
} } /* parent continue */
FILE* fp;
if (*type == 'r') {
close(pfd[]);
if ((fp = fdopen(pfd[], type)) == NULL) {
return NULL;
}
} else {
close(pfd[]);
if ((fp = fdopen(pfd[], type)) == NULL) {
return NULL;
close(pfd[]);
if ((fp = fdopen(pfd[], type)) == NULL) {
return NULL;
}
} childpid[fileno(fp)] = pid;
return fp;
}
 

3. 消息队列

消息队列是消息的链接表,存放在内核中并由消息队列ID标识
msgget用于创建一个新队列或打开一个现存的队列
msgsnd将新消息添加到队列尾端
msgrcv用户从队列中取消息
 

4. 信号量

信号量是一个计数器,用于多进程对共享数据对象的访问
 

5. 共享存储器

共享存储器允许多个进程共享一个给定的存储区,因为数据不需要在客户进程和服务器进程之间复制,所以这是最快的IPC
使用共享存储区时必须确保 多个进程之间对给定的存储区的同步访问,通常,信号量被用来实现对共享存储区的同步访问
#include <sys/shm.h>
/* 获得共享存储标识符 */
int shmget(key_t key, size_t size, int flag); /* 对共享存储区执行多种操作 */
int shmctl(int shmid, int cmd, struct shmid_ds* buf); /* 进程将共享存储区连接到它的地址空间中 */
void* shmat(int shmid, const void* addr, int flag);

如果addr为0,则此段连接到内核选择的第一个可用地址上。一般将addr指定为0,以便由内核选择地址

打印各种不同类型的数据所存放的位置:

 #include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h> #define ARRAY_SIZE 40000
#define MALLOC_SIZE 100000
#define SHM_SIZE 100000
#define SHM_MODE 0600 /* user read/write */ char array[ARRAY_SIZE]; /* uninitialized data = bss */ int main(int argc, char* argv[])
{
int shmid;
char* ptr = NULL;
char* shmptr = NULL; fprintf(stdout, "array[] from %p to %p\n", array, array + ARRAY_SIZE);
fprintf(stdout, "stack around %p\n", &shmid);
ptr = (char*)malloc(MALLOC_SIZE);
if (ptr == NULL) {
fprintf(stderr, "malloc error\n");
} fprintf(stdout, "malloc from %p to %p\n", ptr, ptr + MALLOC_SIZE); shmid = shmget(IPC_PRIVATE, SHM_SIZE, SHM_MODE);
if (shmid < ) {
fprintf(stderr, "shmget error\n");
} shmptr = shmat(shmid, , );
if (shmptr == (void*)-) {
fprintf(stderr, "shmat error\n");
} fprintf(stdout, "shared memory from %p to %p\n", shmptr, shmptr + SHM_SIZE);
if (shmctl(shmid, IPC_RMID, ) < ) {
fprintf(stderr, "shmctl error\n");
}
free(ptr);
return ;
}

在基于Intel的Linux系统上运行此程序,其输出如下:

如果mmap函数指定了 MAP_SHARED标志,则此存储映射区可被多个进程共享
匿名存储映射:调用mmap时指定MAP_ANON标志,并将文件描述符指定为-1,结果得到的映射区域是匿名的,因为并不与一个文件描述符相关联

APUE 学习笔记(十) 高级I/O的更多相关文章

  1. APUE 学习笔记(九) 高级I/O

    1. 非阻塞I/O 低速系统调用时可能会使进程永远阻塞的一类系统调用,包括以下调用: (1)某些文件类型你(网络socket套接字.终端设备.管道)暂无可使用数据,则读操作可能会使调用者永远阻塞 (2 ...

  2. python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例

    python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例 新浪爱彩双色球开奖数据URL:http://zst.aicai.com/ssq/openInfo/ 最终输出结果格 ...

  3. Hadoop学习笔记(7) ——高级编程

    Hadoop学习笔记(7) ——高级编程 从前面的学习中,我们了解到了MapReduce整个过程需要经过以下几个步骤: 1.输入(input):将输入数据分成一个个split,并将split进一步拆成 ...

  4. Learning ROS for Robotics Programming Second Edition学习笔记(十) indigo Gazebo rviz slam navigation

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 moveit是书的最后一章,由于对机械臂完全不知,看不懂 ...

  5. python3.4学习笔记(十八) pycharm 安装使用、注册码、显示行号和字体大小等常用设置

    python3.4学习笔记(十八) pycharm 安装使用.注册码.显示行号和字体大小等常用设置Download JetBrains Python IDE :: PyCharmhttp://www. ...

  6. python3.4学习笔记(十九) 同一台机器同时安装 python2.7 和 python3.4的解决方法

    python3.4学习笔记(十九) 同一台机器同时安装 python2.7 和 python3.4的解决方法 同一台机器同时安装 python2.7 和 python3.4不会冲突.安装在不同目录,然 ...

  7. python3.4学习笔记(十六) windows下面安装easy_install和pip教程

    python3.4学习笔记(十六) windows下面安装easy_install和pip教程 easy_install和pip都是用来下载安装Python一个公共资源库PyPI的相关资源包的 首先安 ...

  8. python3.4学习笔记(十五) 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)

    python3.4学习笔记(十五) 字符串操作(string替换.删除.截取.复制.连接.比较.查找.包含.大小写转换.分割等) python print 不换行(在后面加上,end=''),prin ...

  9. python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL

    python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL实战例子:使用pyspider匹配输出带.html结尾的URL:@config(a ...

随机推荐

  1. 理解AttributeUsage类

    类定义: // 摘要: // 指定另一特性类的用法. 此类不能被继承. [Serializable] [AttributeUsage(AttributeTargets.Class, Inherited ...

  2. C++实现Singleton模式(effective c++ 04)

    阅读effective c++ 04 (31页) 提到的singleton设计模式.了解一下. 定义: 保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享. 应用场景: 比 ...

  3. 主题模型LDA及在推荐系统中的应用

    1 关于主题模型 使用LDA做推荐已经有一段时间了,LDA的推导过程反复看过很多遍,今天有点理顺的感觉,就先写一版. 隐含狄利克雷分布简称LDA(latent dirichlet allocation ...

  4. 【思维题 单调栈】loj#2430. 「POI2014」沙拉餐厅 Salad Bar

    t老师的做法好神…… 题目描述 桌面上有 n 个水果,分别是苹果和橘子.Bytea需要从水果中选择连续的一个区间,并从左到右或从右到左拿水果,且过程中橘子的数量必须始终不小于苹果的数量.求最长的区间大 ...

  5. 【Mysql】Mysql主从库搭建过程(爬完坑后整理所得)

    Mysql主从数据库搭建流程 新手开始学习mysql主从库,遇到一些问题,总结后写出以下流程 下面以5.7.23版本为例介绍 第一步:去官网下载5.7.23版本的免安装压缩包形式的mysql文件,贴上 ...

  6. 【Python学习之五】高级特性4(切片、迭代、列表生成器、生成器、迭代器)

    4.生成器(generator) 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的 ...

  7. 18/07/2017 R matrix

    矩阵:二维数组,元素拥有相同模式(数值型,字符型或者逻辑型) mymatrix <- matrix (vector, nrow_num_of_rows, ncol_num_of_columns, ...

  8. MongoDB之Replica Sets环境搭建

    最近学习MongoDB,这两天在搭建复制集的时候碰到了不少问题,也踩了好多坑,现在在这里记录下来,以供自己和他人参考 (因为本人是初学者,所以遇到的问题也会比较初级,所以本文也比较适合初学者查阅) 背 ...

  9. ACM-ICPC 2016 Qingdao Preliminary Contest G. Sort

    Recently, Bob has just learnt a naive sorting algorithm: merge sort. Now, Bob receives a task from A ...

  10. C语言指针分析

    /*************1*************/ int p; //p是一个普通的整型变量. /*************2*************/ int *p; //p与*结合,说明 ...