AF_UNIX socket开销?

前端之家收集整理的这篇文章主要介绍了AF_UNIX socket开销?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我看到一些奇怪的东西,一对AF_UNIX插座创建的呼叫,如:
  1. socketpair(AF_UNIX,SOCK_STREAM,sfd);

其中sfd是文件描述符的int [2]数组。

首先,默认缓冲区大小似乎是122K(124928字节),而不是/ proc / sys / net(如wmem_default,设置为128K)的任何东西。有没有人知道这个奇怪的缓冲区大小的原因?

第二,当通过套接字写入小消息(8字节)时。我只能在写入块之前写入其中的423个,这只有8 * 423 = 3384字节,另一个奇数的大小。这些消息的作用就好像它们每个占用了一点点字节一样。这个开销的来源是什么?

在RHEL6上运行(2.6.32,64位)

我写了一个程序来尝试不同大小的数据来比较间接成本:

  1. #include <errno.h>
  2. #include <stdio.h>
  3. #include <stdint.h>
  4. #include <stdlib.h>
  5. #include <unistd.h>
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8. #include <netinet/in.h>
  9.  
  10. #define DATA_SIZE 4
  11.  
  12. void run(size_t size) {
  13. int sfd[2];
  14. if (socketpair(AF_UNIX,sfd) == -1) {
  15. perror("error");
  16. }
  17.  
  18.  
  19. int sndbuf,sbsize = sizeof(sndbuf);
  20. getsockopt(sfd[0],SOL_SOCKET,SO_SNDBUF,&sndbuf,(socklen_t*)&sbsize);
  21.  
  22. printf("Data Size: %zd\n",size);
  23. char buff[size];
  24. size_t wrote=0;
  25. for (size_t ii=0; ii < 32768; ii++) {
  26. if ((send(sfd[0],buff,size,MSG_DONTWAIT) == -1) && (errno == EAGAIN)) {
  27. wrote = ii;
  28. break;
  29. }
  30. }
  31.  
  32. printf("Wrote: %zd\n",wrote);
  33.  
  34. if (wrote != 0) {
  35. int bpm = sndbuf/wrote;
  36. int oh = bpm - size;
  37.  
  38. printf("Bytes/msg: %i\n",bpm);
  39. printf("Overhead: %i\n",oh);
  40. printf("\n");
  41. }
  42.  
  43. close(sfd[0]); close(sfd[1]);
  44. }
  45.  
  46. int main() {
  47. int sfd[2];
  48. socketpair(AF_UNIX,sfd);
  49.  
  50. int sndbuf,(socklen_t*)&sbsize);
  51.  
  52. printf("Buffer Size: %i\n\n",sndbuf);
  53. close(sfd[0]); close(sfd[1]);
  54.  
  55. for (size_t ii=4; ii <= 4096; ii *= 2) {
  56. run(ii);
  57. }
  58. }

这使:

  1. Buffer Size: 124928
  2.  
  3. Data Size: 4
  4. Wrote: 423
  5. Bytes/msg: 295
  6. Overhead: 291
  7.  
  8. Data Size: 8
  9. Wrote: 423
  10. Bytes/msg: 295
  11. Overhead: 287
  12.  
  13. Data Size: 16
  14. Wrote: 423
  15. Bytes/msg: 295
  16. Overhead: 279
  17.  
  18. Data Size: 32
  19. Wrote: 423
  20. Bytes/msg: 295
  21. Overhead: 263
  22.  
  23. Data Size: 64
  24. Wrote: 423
  25. Bytes/msg: 295
  26. Overhead: 231
  27.  
  28. Data Size: 128
  29. Wrote: 348
  30. Bytes/msg: 358
  31. Overhead: 230
  32.  
  33. Data Size: 256
  34. Wrote: 256
  35. Bytes/msg: 488
  36. Overhead: 232
  37.  
  38. Data Size: 512
  39. Wrote: 168
  40. Bytes/msg: 743
  41. Overhead: 231
  42.  
  43. Data Size: 1024
  44. Wrote: 100
  45. Bytes/msg: 1249
  46. Overhead: 225
  47.  
  48. Data Size: 2048
  49. Wrote: 55
  50. Bytes/msg: 2271
  51. Overhead: 223
  52.  
  53. Data Size: 4096
  54. Wrote: 29
  55. Bytes/msg: 4307
  56. Overhead: 211

与管道相比,绝对有很多开销:

  1. Data Size: 4
  2. Wrote: 16384
  3. Bytes/msg: 4
  4. Overhead: 0
  5.  
  6. Data Size: 8
  7. Wrote: 8192
  8. Bytes/msg: 8
  9. Overhead: 0
  10.  
  11. Data Size: 16
  12. Wrote: 4096
  13. Bytes/msg: 16
  14. Overhead: 0
  15.  
  16. Data Size: 32
  17. Wrote: 2048
  18. Bytes/msg: 32
  19. Overhead: 0
  20.  
  21. Data Size: 64
  22. Wrote: 1024
  23. Bytes/msg: 64
  24. Overhead: 0
  25.  
  26. Data Size: 128
  27. Wrote: 512
  28. Bytes/msg: 128
  29. Overhead: 0
  30.  
  31. Data Size: 256
  32. Wrote: 256
  33. Bytes/msg: 256
  34. Overhead: 0
  35.  
  36. Data Size: 512
  37. Wrote: 128
  38. Bytes/msg: 512
  39. Overhead: 0
  40.  
  41. Data Size: 1024
  42. Wrote: 64
  43. Bytes/msg: 1024
  44. Overhead: 0
  45.  
  46. Data Size: 2048
  47. Wrote: 32
  48. Bytes/msg: 2048
  49. Overhead: 0
  50.  
  51. Data Size: 4096
  52. Wrote: 16
  53. Bytes/msg: 4096
  54. Overhead: 0
看看插座(7)手册页。有一个部分如下:

SO_SNDBUF
Sets or gets the maximum socket send buffer in bytes. The kernel doubles this value
(to allow space for bookkeeping overhead) when it is set using setsockopt(2),and this
doubled value is returned by getsockopt(2). The default value is set by the
/proc/sys/net/core/wmem_default file and the maximum allowed value is set by the
/proc/sys/net/core/wmem_max file. The minimum (doubled) value for this option is
2048.

所以看起来,开销仅仅是为了保存内核的簿记信息。

猜你在找的Bash相关文章