c++ fork 进程时 共享内存_网络编程:进程间通信性能比较

unix/linux下的进程间通信有很多种方法,如:

  • 匿名管道(pipe):父子进程间的通信
  • 命名管道(fifo):可以和无关联进程的通信
  • 共享内存(shm):可以和无关联进程的通信,需要自己处理进程同步,比如和信号量配合。
  • unix域套接字(unix socket):可以和无关联进程的通信,使用socket接口。
  • 网域套接字(internet socket):可以跨主机通信,使用socket接口。
  • 等等

这些方案各有自己的特点:

  • 比如通常我们能确定共享内存一定是最快的,因为它通过将虚拟内存映射到相同的物理内存,使得两个进程可以操作相同的内存,但是它只是普通的内存操作,需要我们自己处理同步问题,以及如何通知其他进程。总结起来就是不大好用,并且如果加了同步机制之后,性能还会很快吗?
  • 匿名管道很好用,不过只能在有关联的进程间使用(父子进程),命名管道可以在任意进程使用,但的性能到底如何?
  • unix套接字的好处是使用相同的socket接口,我们可以设计一个抽象层,把它和TCP/UDP统一起来。前提当然是假设它在本机的进程间通信要好于TCP/UDP。
  • 网域套接字的好处更明显了,可以本机(使用回环地址),也可以在网络上通信,一套接口通用性很好。

这些IPC方法的吞吐量到底怎么样呢?github上有一个项目对这些方法作了性能测试,不过有一些小问题,我fork了过来修改了一下,并且加上共享内存的测试,放在这里: https://github.com/colinsusie/ipc_benchmark

这里就不贴代码了,直接上测试结果

测试环境是虚拟机:两核的Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz,系统是debian 8

+------------+--------------+--------------+---------------+---------------+---------------+----------------+
| test/size  | 128 x 100000 | 256 x 100000 |  512 x 100000 | 1024 x 100000 | 2048 x 100000 | 4096 x 100000  |
+------------+--------------+--------------+---------------+---------------+---------------+----------------+
|    pipe    |   186MB/s    |   309MB/s    |    502MB/s    |    848MB/s    |    1328MB/s   |    1667MB/s    |
|    fifo    |    51MB/s    |    90MB/s    |    192MB/s    |    445MB/s    |    1002MB/s   |    1837MB/s    |
| socketpair |    61MB/s    |   148MB/s    |    311MB/s    |    655MB/s    |    952MB/s    |    1989MB/s    |
|    uds     |    86MB/s    |   146MB/s    |    317MB/s    |    689MB/s    |    922MB/s    |    2023MB/s    |
|    tcp     |    97MB/s    |   158MB/s    |    334MB/s    |    578MB/s    |    745MB/s    |    1014MB/s    |
|    shm     | 4.768381MB/s | 8.698946MB/s | 18.034129MB/s | 35.899021MB/s | 78.708005MB/s | 142.803191MB/s |
+------------+--------------+--------------+---------------+---------------+---------------+----------------+

方法是创建父子进程,由一个进程向另一个进程写100000次数据,数据大小从128到4096。结果很让人差异,fifo的效率比pipe差2倍,而共享内存因为加了信号量之后性能非常差。

上面结果也引来一些人的疑问,为此我找了另一台虚拟机:4核的Intel(R) Xeon(R) CPU E5-26xx v4,,系统是仍然debian 8, 结果如下:

+------------+---------------+----------------+---------------+----------------+---------------+-----------------+
| test/size  |  128 x 100000 |  256 x 100000  |  512 x 100000 | 1024 x 100000  | 2048 x 100000 |  4096 x 100000  |
+------------+---------------+----------------+---------------+----------------+---------------+-----------------+
|    pipe    |    220MB/s    |    383MB/s     |    672MB/s    |    1378MB/s    |    2108MB/s   |     1641MB/s    |
|    fifo    |    183MB/s    |    350MB/s     |    654MB/s    |    1182MB/s    |    1731MB/s   |     1751MB/s    |
| socketpair |    180MB/s    |    343MB/s     |    649MB/s    |    1161MB/s    |    1953MB/s   |     2991MB/s    |
|    uds     |    134MB/s    |    339MB/s     |    549MB/s    |    1148MB/s    |    2119MB/s   |     2776MB/s    |
|    tcp     |    228MB/s    |    657MB/s     |    1125MB/s   |    1805MB/s    |    1608MB/s   |     2201MB/s    |
|    shm     | 55.320491MB/s | 108.505956MB/s | 35.058660MB/s | 474.144318MB/s | 96.502366MB/s | 1753.450929MB/s |
+------------+---------------+----------------+---------------+----------------+---------------+-----------------+

这回fifo和pipe差不多了,为了验证是否第1台虚拟机有问题,我又找了一个和第1台相同配置的虚拟机(没办法机器多),测试结果如下:

+------------+--------------+--------------+---------------+---------------+---------------+----------------+
| test/size  | 128 x 100000 | 256 x 100000 |  512 x 100000 | 1024 x 100000 | 2048 x 100000 | 4096 x 100000  |
+------------+--------------+--------------+---------------+---------------+---------------+----------------+
|    pipe    |   153MB/s    |   285MB/s    |    515MB/s    |    913MB/s    |    1670MB/s   |    2287MB/s    |
|    fifo    |   144MB/s    |   264MB/s    |    481MB/s    |    877MB/s    |    1566MB/s   |    2343MB/s    |
| socketpair |   155MB/s    |   290MB/s    |    586MB/s    |    1014MB/s   |    1843MB/s   |    2566MB/s    |
|    uds     |   136MB/s    |   267MB/s    |    564MB/s    |    920MB/s    |    1704MB/s   |    2626MB/s    |
|    tcp     |   249MB/s    |   339MB/s    |    760MB/s    |    1373MB/s   |    1971MB/s   |    2815MB/s    |
|    shm     | 3.514287MB/s | 7.406006MB/s | 14.468472MB/s | 28.211735MB/s | 54.214965MB/s | 109.995927MB/s |
+------------+--------------+--------------+---------------+---------------+---------------+----------------+

fifo和pipe也差不多,第1台虚拟机不知道什么原因导致性能上的差距,我用/bin/time分别调用了fifo和pipe发现:

# pipe
Percent of CPU this job got: 83%
Voluntary context switches: 63
Involuntary context switches: 1477
...

# fifo
Percent of CPU this job got: 48%
Voluntary context switches: 306
Involuntary context switches: 55582
...

fifo的CPU利用率并不高,时间都耗在强制的进程切换上了,至于为什么会有这么多的进程切换,我没有想明白。

但从其他两台机器的结果看,fifo和pipe是差不多的,而TCP一直都表现得很好。

另外关于共享内存的高性能测试,请看这个文章:

co lin:进程间通讯:RingBuffer的性能测试​zhuanlan.zhihu.com
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值