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. 2.Helloworld

    1.对于Qt程序来说,main()函数一般以创建application对象(gui是QApplication,非gui程序是QCoreApplication.QApplication实际上是QCore ...

  2. print显示特定的数据格式

    原文网址 1.查看数据print  variable        查看变量print  *array@len      查看数组(array是数组指针,len是需要数据长度)可以通过添加参数来设置输 ...

  3. 利用Snapshot快速跨Region迁移服务器

    当你需要对现有的网站进行跨区域迁移,或者是部署DR Site的时候,又不希望重新部署应用,有什么好办法呢?其实你可以利用Azure的磁盘snapshot进行磁盘级的复制,这样可以减少很多部署应用的时间 ...

  4. python pip安装--不是内部或外部命令--解决方案

    首先在 命令行中输入 python -m ensurepip 创建出pip3.exe  , 并找到pip3.exe所在的Scripts路径 使命令行在Scripts路径下 输入pip3 install ...

  5. python基础之map/reduce/filter/sorted

    ---map(fun,iterable) 首先来看一看map()函数,map函数接受两个参数,第一个参数是函数的名称,第二个参数一个可迭代对象.即map(fun,iterable) map函数就是将具 ...

  6. Python【异常处理】

    def f(): first = input('请输入除数:') second = input('请输入被除数:') try: first = int(first) second = int(seco ...

  7. 转:Launch Screen在iOS7/8中的实现

    目前项目中需要解决的问题是: 兼容iOS7和iOS8,之前的版本不需要支持了 实现兼容3.5.4.4.7和5.5寸屏幕,竖屏的Lauch Screen 创建所需的PNG图片 有关iPhone6/6+相 ...

  8. C++ Rule of Three

    Rule of Three The rule of three (also known as the Law of The Big Three or The Big Three) is a rule ...

  9. 点击搜索条件提交form表单

    思路:点击搜索,javascript跳转提交方法,提交整个表单. //组员下拉框选择分组事件 $('#s-member').change(function(){ $('#logForm').submi ...

  10. 使用win10 hyper-v安装linux系统

    1.控制面板---程序---启动或关闭windows功能---启动hyper-v管理器---重启 2.配置网络 因为公司内网通过ip验证,而通过桥接的方式,虚拟机就相当于物理机所在的网络中的一台真实主 ...