Linux下的IPC机制

IPC(Inter-Process Communication)是多个进程之间相互沟通的一种方法。在linux下有多种进程间通信的方法。

共享内存

Linux内存共享有多种,如mmap()、Posix共享内存、System V 共享内存。

1>mmp()通过映射一个普通文件实现共享内存,具有文件实体,shmget()对应文件在内存中,无文件实体。

2>mmp()不建议使用叠加方式共享,shmget()用于多个进程间交换数据。

3>mmp() shmget() 进程重启后共享内存中的数据都不会丢失;但是机器重启后只有mmp()方式的共享内存可以保存数据

4>mmap()接口更简单,通用性也更高。

这里首先先使用shmget建立一块共享内存,然后向该内存中写入数据并返回该共享内存shmid。使用另一个程序通过上一程序返回的shmid读该共享内存内的数据

建立共享内存并写入数据的程序:

#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <errno.h>
void get_buf(char *buf)
{
int i=0;
while((buf[i]=getchar())!='\n'&&i<1024)
i++;
}
int main(void)
{
int shmid;
shmid=shmget(IPC_PRIVATE,sizeof(char)*1024,IPC_CREAT|0666);
if(shmid==-1)
{
perror("shmget");
}
char *buf;
if((int)(buf=shmat(shmid,NULL,0))==-1)
{
perror("shmat");
exit(1);
}
get_buf(buf);
printf("%d\n",shmid);
return 0;
}
读取数据的程序
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
int main(int argc,char **argv)
{
int shmid;
shmid=atoi(argv[1]);
char *buf;
if((int)(buf=shmat(shmid,NULL,0))==-1)
{
perror("shmat");
exit(1);
}
printf("%s\n",buf);
shmdt(buf);
return 0;
}

管道

管道是由内核管理的一个缓冲区,创建管道的进程称为管道服务器,连接到一个管道的进程为管道客户机。一个进程在向管道写入数据后,另一进程就可以从管道的另一端将其读取出来。

管道的特点:

1、管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;

2、一般只能用于父子进程之间。

3、单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。

4、数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。

管道程序实例(创建一个从父进程到子进程的管道,并且父进程经由该管道向子进程传送数据):

  #include <unistd.h>
#include <stdio.h> #define MAXLINE 1024 int main(void)
{
int n;
int fd[2];
pid_t pid;
char line[MAXLINE]; if (pipe(fd) < 0)
printf("pipe error\n");
if ((pid = fork()) < 0) {
printf("fork error\n");
} else if (pid > 0) { /* parent */
close(fd[0]);
write(fd[1], "hello world\n", 12); /* write data to fd[1] */
} else { /* child */
close(fd[1]);
n = read(fd[0], line, MAXLINE); /* read data from fd[0] */
write(STDOUT_FILENO, line, n); /* write data to standard output */
} return (0);
}

FIFO

FIFO有时被称为命名管道,未命名的管道只能在两个相关的进程之间使用,而且这两个相关的进程还要有一个共同的祖先进程。但是,通过FIFO,不相关的进程之间也能交换数据。

FIFO的用途:用于客户进程--服务器进程应用程序中

FIFO的真正优势在于:服务器可以是一个长期运行的进程(例如守护进程),而且与其客户可以无亲缘关系。

实例:需要对一个输入文件进行两次处理

可以使用FIFO和tee命令如下处理:

mkfifo fifo1

prog3 < fifo1 &

prog1 < (输入文件) | tee fifo1 | prog2

执行流程如下:

信号

信号用于一个或几个进程之间传递异步信号。信号可以有各种异步事件产生,比如键盘中断等。shell也可以使用信号将作业控制命令传递给它的子进程。

实例(向进程本身发送信号,并传递指针参数,信号实现了附加信息的传递):

#include <signal.h>

#include <sys/types.h>

#include <unistd.h>

void new_op(int,siginfo_t*,void*);

int main(int argc,char**argv)

{

struct sigaction act;

union sigval mysigval;

int i;

int sig;

pid_t pid;

char data[10];

memset(data,0,sizeof(data));

for(i=0;i < 5;i++)

data[i]='2';

mysigval.sival_ptr=data;

sig=atoi(argv[1]);

pid=getpid();

sigemptyset(&act.sa_mask);

act.sa_sigaction=new_op;//三参数信号处理函数

act.sa_flags=SA_SIGINFO;//信息传递开关

if(sigaction(sig,&act,NULL) < 0)

{

printf("install sigal error\n");

}

while(1)

{

sleep(2);

printf("wait for the signal\n");

sigqueue(pid,sig,mysigval);//向本进程发送信号,并传递附加信息

}

}

void new_op(int signum,siginfo_t *info,void *myact)//三参数信号处理函数的实现

{

int i;

for(i=0;i<10;i++)

{

printf("%c\n ",(*( (char*)((*info).si_ptr)+i)));

}

printf("handle signal %d over;",signum);

}

消息队列

消息队列是内核地址空间中的内部链表,通过linux内核在各个进程直接传递内容,消息顺序地发送到消息队列中,并以几种不同的方式从队列中获得,每个消息队列可以用IPC标识符唯一地进行识别。内核中的消息队列是通过IPC的标识符来区别,不同的消息队列直接是相互独立的。每个消息队列中的消息,又构成一个独立的链表。

消息队列克服了信号承载信息量少,管道只能承载无格式字符流。

消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构。我们可以通过发送消息来避免命名管道的同步和阻塞问题。但是消息队列与命名管道一样,每个数据块都有一个最大长度的限制。

参考资料:

Linux 进程间通信(一)(经典IPC:管道、FIFO)

linux基础——linux进程间通信(IPC)机制总结

linux下IPC机制之“内存共享”

Linux下内存共享的一个实例(设置共享内存,一个程序写,一个程序读)

Linux下的IPC机制的更多相关文章

  1. 2017-2018-1 20155222 《信息安全系统设计基础》第10周 Linux下的IPC机制

    2017-2018-1 20155222 <信息安全系统设计基础>第10周 Linux下的IPC机制 IPC机制 在linux下的多个进程间的通信机制叫做IPC(Inter-Process ...

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

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

  3. Linux下的IPC几种通信方式

    Linux下的IPC几种通信方式 管道(pipe):管道可用于具有亲缘关系的进程间的通信,是一种半双工的方式,数据只能单向流动,允许一个进程和另一个与它有公共祖先的进程之间进行通信. 命名管道(nam ...

  4. Linux下的IPC-UNIX Domain Socket【转】

    本文转载自:http://blog.csdn.net/guxch/article/details/7041052 一. 概述 UNIX Domain Socket是在socket架构上发展起来的用于同 ...

  5. linux下epoll实现机制

    linux下epoll实现机制 原作者:陶辉 链接:http://blog.csdn.net/russell_tao/article/details/7160071 先简单回顾下如何使用C库封装的se ...

  6. linux下关于IPC(进程间通信)

    linux下进程间通信的主要几种方式 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许 ...

  7. Linux 下的同步机制

    2017-03-10 回想下最初的计算机设计,在单个CPU的情况下,同一时刻只能由一个线程(在LInux下为进程)占用CPU,且2.6之前的Linux内核并不支持内核抢占,当进程在系统地址运行时,能打 ...

  8. linux下进程间通信的机制

    今天突然想起了nginx解决惊群的方法,就是在多个进程间利用锁来保证同一时刻只能有一个worker进程在自己的epoll中加入监听的句柄,那么进程间是怎么共享变量的呢,下面就介绍一下共享内存 共享内存 ...

  9. 【操作系统之三】Linux下进程间通信-IPC(Inter-Process Communication)

    管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信:信号(Sign ...

随机推荐

  1. WARNING: pgstat wait timeout

      在ELK的邮件报警中,发现了一个 WARNING: pgstat wait timeout 的报错信息,看字面意思是pgstat有关操作等待超时.   通过google查询,发现在pg的邮件列表中 ...

  2. springboot中如何添加第三方的jar包或者说如何配置本地jar

    首先推荐博客: spring-boot-maven-plugin 安装本地jar 包 http://www.cnblogs.com/acm-bingzi/p/mavenSpringBootPlugin ...

  3. table 样式美化

    1. 单像素边框CSS表格 这是一个很常用的表格样式. 源代码: <!-- CSS goes in the document HEAD or added to your external sty ...

  4. location.href跳转测试

    测试代码 <script type="text/javascript"> function ToUrl(x){ location.href=x; } </scri ...

  5. Shell记录-Shell命令(其他)

    top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器. .命令格式 top [参数] Shell 2.命令功能 显示当前系统正在执行的 ...

  6. 《设计模式》-原则四:接口隔离原则(ISP)

    啊!天气很热啊,回来洗个澡,做个饭吃完后 又出了一身汗,真后悔先洗澡. 加油坚持学习,今天要学的是“接口隔离原则” 意思是说:在设计的时候使用多个专门的接口比使用一个总的接口好很多.一个类对另一个类的 ...

  7. 一个JavaScript组件都需要哪些基础api

    { init: function() { // 模块初始化,包括属性初始化和配置初始化及调用父类的初始化方法 } ,build: function() { // 模块构建,包括子模块构建,dom构建, ...

  8. 三个你不知道的CSS技巧

    各种浏览器之间的竞争的白热化意味着越来越多的人现在开始使用那些支持最新.最先进的W3C Web标准的设备,以一种更具交互性的方式来访问互联网.这意味着我们终于能够利用更强大更灵活的CSS来创造更简洁, ...

  9. win7下设置挂载Linux服务器nfs共享的数据 -- 转

    最近学习NFS文件系统的使用,Ubuntu上配置好了,想和Win7共享数据,所以网上搜到了这篇文章.借花献佛,跟大家共享一下: http://www.2cto.com/os/201207/139132 ...

  10. Let Me Count The Ways(Kickstart Round H 2018)

    题目链接:https://code.google.com/codejam/contest/3324486/dashboard#s=p2 题目: 思路: 代码实现如下: #include <set ...