linux 单机跨进程通信
一般来说通过网络通信(比如tcp,udp)或者共享内存的方式肯定可以实现跨进程通信,但现在这里要说的是比较偏但实用的几个方法:利用unix域通信(普通网络连接),利用unix域通信(socketpair通信),以及pipe方式。
一. 利用unix域通信(普通网络连接)
socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC更有效率:不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。UNIX域套接字与TCP套接字相比较,在同一台主机的传输速度前者是后者的两倍。这是因为,IPC机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。UNIX Domain Socket也提供面向流和面向数据包两种API接口,类似于TCP和UDP,但是面向消息的UNIXDomain Socket也是可靠的,消息既不会丢失也不会顺序错乱。
使用UNIX Domain Socket的过程和网络socket十分相似,也要先调用socket()创建一个socket文件描述符,address family指定为AF_UNIX,type可以选择SOCK_DGRAM或SOCK_STREAM,protocol参数仍然指定为0即可。
UNIX Domain Socket与网络socket编程最明显的不同在于地址格式不同,用结构体sockaddr_un表示,网络编程的socket地址是IP地址加端口号,而UNIX Domain Socket的地址是一个socket类型的文件在 文件系统中的路径 ,这个socket文件由bind()调用创建,如果调用bind()时该文件已存在,则bind()错误返回。
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <string>
using std::string; void serverService()
{
int listenfd = socket(AF_UNIX, SOCK_STREAM, );
if(listenfd == -)
{
perror("create listen fd error.");
exit(-);
} char pathname[] = "/tmp/my.sock";
unlink(pathname);//如果文件系统中已存在该路径名,bind将会失败。为此我们先调用unlink删除这个路径名,以防止它已经存在
struct sockaddr_un servAddr;
servAddr.sun_family = AF_UNIX;
strcpy(servAddr.sun_path, pathname);
if (bind(listenfd, (struct sockaddr *)&servAddr, sizeof(servAddr)) == -) // 若成功会创建pathname文件
perror("bind error");
if (listen(listenfd, SOMAXCONN) == -)
perror("listen error"); while ()
{
int connfd = accept(listenfd, NULL, NULL);
if (connfd == -)
{
if(connfd==EINTR)
continue;
perror("accept");
}
else
{
char buffer[] = "i am a boy.";
write(connfd, buffer, sizeof(buffer));
close(connfd);
}
}
} void clientService()
{
int sockfd = socket(AF_UNIX, SOCK_STREAM, );
if (sockfd == -)
perror("socket error"); char pathname[] = "/tmp/my.sock";
struct sockaddr_un servAddr;
servAddr.sun_family = AF_UNIX;
strcpy(servAddr.sun_path, pathname);
if (connect(sockfd, (struct sockaddr *)&servAddr, sizeof(servAddr)) == -)
perror("connect error"); char buffer[];
read(sockfd, buffer, sizeof(buffer));
printf("read data is [%s]", buffer);
close(sockfd);
} int main(int argc, char* argv[])
{
if(argc != )
{
perror("command error.");
exit(-);
} string service(argv[]);
if(service == "client")
{
clientService();
}
else if(service == "server")
{
serverService();
}
else
{
perror("command error.");
return -;
} return ;
}
二. 利用unix域通信(socketpair通信)
实际上socketpair 函数跟pipe 函数是类似的,也只能在同个主机上具有亲缘关系的进程间通信,但pipe 创建的匿名管道是半双工的,而socketpair 可以认为是创建一个全双工的管道。可参见nginx对此种通信的使用。
函数原型: int socketpair(int domain, int type, int protocol, int sv[2]);
由此可见,上述例子中的通过普通的网络连接建立的unix通信也可以使用这种方式进行。
三. pipe通信
pipe是半双工的,一端要么只能读,要么只能写,不能混用。
linux 单机跨进程通信的更多相关文章
- 【Chromium中文文档】跨进程通信 (IPC)
跨进程通信 (IPC) 转载请注明出处:https://ahangchen.gitbooks.io/chromium_doc_zh/content/zh//General_Architecture/I ...
- 【朝花夕拾】Android性能篇之(七)Android跨进程通信篇
前言 只要是面试高级工程师岗位,Android跨进程通信就是最受面试官青睐的知识点之一.Android系统的运行由大量相互独立的进程相互协助来完成的,所以Android进程间通信问题,是做好Andro ...
- 图文详解 Android Binder跨进程通信机制 原理
图文详解 Android Binder跨进程通信机制 原理 目录 目录 1. Binder到底是什么? 中文即 粘合剂,意思为粘合了两个不同的进程 网上有很多对Binder的定义,但都说不清楚:Bin ...
- Android随笔之——跨进程通信(一) Activity篇
在Android应用开发中,我们会碰到跨进程通信的情况,例如:你用QQ通讯录打电话的时候会调用系统的拨号应用.某些新闻客户端可以将新闻分享到QQ.微信等应用,这些都是跨进程通信的情况.简而言之,就是一 ...
- WinForm实现跨进程通信的方法
public class WinMessageHelper { private struct COPYDATASTRUCT { public IntPtr dwData; public int cbD ...
- AIDL跨进程通信
Android跨进程通信会用到AIDL,当然跨进程通信不一定要用AIDL,像广播也是可以的,当然这里用到AIDL相对比较安全一些: AIDL允许传递基本数据类型(Java 的原生类型如int/long ...
- Android中的跨进程通信方法实例及特点分析(二):ContentProvider
1.ContentProvider简单介绍 在Android中有些数据(如通讯录.音频.视频文件等)是要供非常多应用程序使用的.为了更好地对外提供数据.Android系统给我们提供了Content P ...
- 跨进程通信之Messenger
1.简介 Messenger,顾名思义即为信使,通过它可以在不同进程中传递Message对象,通过在Message中放入我们需要的入局,就可以轻松实现数据的跨进程传递了.Messenger是一种轻量级 ...
- 不依赖AIDL的跨进程通信
http://blog.csdn.net/lmj623565791/article/details/38461079 如果知道AIDL和binder的原理,可以简单写一个不依赖AIDL的跨进程通信 不 ...
随机推荐
- Spring:与Redis的集成
一个月没写过博客了,一直想记录一下之前学习的Redis的有关知识,但是因为四月太过于慵懒和忙碌,所以一直没有什么机会,今天就来讲讲,如何使用Spring当中的Spring-data-redis去与Re ...
- Bellman - Ford 算法解决最短路径问题
Bellman - Ford 算法: 一:基本算法 对于单源最短路径问题,上一篇文章中介绍了 Dijkstra 算法,但是由于 Dijkstra 算法局限于解决非负权的最短路径问题,对于带负权的图就力 ...
- CentOS 安装 Zookeeper 版本任选
Zookeeper下载地址各种版本自己选择: https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/ Zookeeper 3.4.13版本下载地址 ...
- LoadRunner系列之---web_set_sockets_options,解决No buffer space available错误
1. 如果在系统运行过程中出现"No buffer space available"或者出现大量连接出现wait的时候, 如何解决? 解决办法: 保证迭代结束后关闭所有的链接: 在 ...
- 某考试 T1 lcm
把lcm写成 (a+n)*(b+n) / gcd(a+n,b+n). 因为gcd可以辗转相减,所以就成了gcd(abs(a-b),a+n),一个常量一个变量之间的gcd,我们可以直接把abs(a-b) ...
- [BZOJ2527]Meteors
整体二分挺好玩的...学一发 这个询问显然是可以二分的,但每次都二分就会T爆,所以我们有了“整体”二分 每次处理一些询问,要求这些询问的答案一定在$[l,r]$中 先把$l$到$mid$的操作实施,那 ...
- [CF935F]Fafa and Array
法法round(雾 题意:给一个序列$a_{1\cdots n}$,定义$\begin{align*}f=\sum\limits_{i=1}^{n-1}\left|a_i-a_{i+1}\right| ...
- 【离线】【递推】【multiset】 Codeforces Round #401 (Div. 2) C. Alyona and Spreadsheet
对询问按右端点排序,对每一列递推出包含当前行的单调不下降串最多向前延伸多少. 用multiset维护,取个最小值,看是否小于等于该询问的左端点. #include<cstdio> #inc ...
- gnuplot加速比比较图
1)使用gnuplot画图代码如下: :] :] set xlabel "分片数" set ylabel "加速比" plot : w lp pt ps tit ...
- iOS开发——异常:[__NSCFNumber length]: unrecognized selector sent to instance
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumbe ...