msg_send.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
  2. /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <unistd.h>
  7. #include <sys/types.h>
  8. #include <sys/ipc.h>
  9. #include <sys/msg.h>
  10. #include <sys/time.h>
  11. #include <sys/wait.h>
  12. #define PAYLOAD_SIZE 10
  13. struct msgbuf {
  14. long mtype;
  15. char mtext[PAYLOAD_SIZE];
  16. };
  17. #define TEST_TIMES 1000
  18. #define TEST_TYPES 2
  19. #define DO_BENCH 1
  20. enum { PARALLEL, SERIAL, IN_PROCESS } mode = PARALLEL;
  21. int pipefds[4], key;
  22. /* server always sends messages */
  23. void server (void)
  24. {
  25. struct timeval tv1, tv2;
  26. int msqid;
  27. struct msgbuf buf;
  28. if ((msqid = msgget(key, mode == SERIAL ? 0600|IPC_CREAT : 0)) < 0) {
  29. perror("msgget");
  30. exit(1);
  31. }
  32. gettimeofday(&tv1, NULL);
  33. for (int i = 0 ; i < TEST_TIMES ; i++) {
  34. buf.mtype = (i % TEST_TYPES) + 1;
  35. if (msgsnd(msqid, &buf, PAYLOAD_SIZE, 0) < 0) {
  36. perror("msgsnd");
  37. exit(1);
  38. }
  39. #ifndef DO_BENCH
  40. printf("Message: \"%s\" sent\n", buf.mtext);
  41. #endif
  42. }
  43. gettimeofday(&tv2, NULL);
  44. if (mode == PARALLEL) {
  45. char byte = 0;
  46. close(pipefds[0]);
  47. write(pipefds[1], &byte, 1);
  48. close(pipefds[3]);
  49. read(pipefds[2], &byte, 1);
  50. }
  51. printf("time spent on %d msgsnd: %llu microsecond\n",
  52. TEST_TIMES,
  53. (tv2.tv_sec * 1000000ull + tv2.tv_usec) -
  54. (tv1.tv_sec * 1000000ull + tv1.tv_usec));
  55. if (mode != IN_PROCESS)
  56. exit(0);
  57. }
  58. /* client always sends messages */
  59. void client (void)
  60. {
  61. struct timeval tv1, tv2;
  62. int msqid;
  63. struct msgbuf buf;
  64. int ret;
  65. if (mode == PARALLEL) {
  66. char byte = 0;
  67. close(pipefds[1]);
  68. read(pipefds[0], &byte, 1);
  69. }
  70. if ((msqid = msgget(key, 0)) < 0) {
  71. perror("msgget");
  72. exit(1);
  73. }
  74. gettimeofday(&tv1, NULL);
  75. for (int i = 0 ; i < TEST_TIMES ; i++) {
  76. int type = (i % TEST_TYPES) + 1;
  77. if ((ret = msgrcv(msqid, &buf, PAYLOAD_SIZE, type, 0)) < 0) {
  78. perror("msgrcv");
  79. exit(1);
  80. }
  81. #ifndef DO_BENCH
  82. buf.mtext[ret] = 0;
  83. printf("Client received: \"%s\"\n", buf.mtext);
  84. #endif
  85. }
  86. gettimeofday(&tv2, NULL);
  87. if (mode == PARALLEL) {
  88. char byte = 0;
  89. close(pipefds[2]);
  90. write(pipefds[3], &byte, 1);
  91. }
  92. printf("time spent on %d msgrcv: %llu microsecond\n",
  93. TEST_TIMES,
  94. (tv2.tv_sec * 1000000ull + tv2.tv_usec) -
  95. (tv1.tv_sec * 1000000ull + tv1.tv_usec));
  96. if (mode != IN_PROCESS)
  97. exit(0);
  98. }
  99. int main (int argc, char ** argv)
  100. {
  101. int msqid;
  102. key = rand();
  103. #ifndef DO_BENCH
  104. printf("Msg queue key: 0x%8x\n", key);
  105. #endif
  106. /* server run first and client run later */
  107. if (argc == 2 && strcmp(argv[1], "serial") == 0) {
  108. mode = SERIAL;
  109. if (fork() == 0)
  110. server();
  111. wait(NULL);
  112. if (fork() == 0)
  113. client();
  114. wait(NULL);
  115. return 0;
  116. }
  117. if ((msqid = msgget(key, 0600|IPC_CREAT)) < 0) {
  118. perror("msgget");
  119. exit(1);
  120. }
  121. /* server run first and client run later (in the same process) */
  122. if (argc == 2 && strcmp(argv[1], "in-process") == 0) {
  123. mode = IN_PROCESS;
  124. server();
  125. client();
  126. msgctl(msqid, IPC_RMID, NULL);
  127. return 0;
  128. }
  129. pipe(&pipefds[0]);
  130. pipe(&pipefds[2]);
  131. /* server to be the parent and client to be the child */
  132. if (argc == 1) {
  133. if (fork() == 0)
  134. client();
  135. else
  136. server();
  137. }
  138. /* client to be the parent and server to be the child */
  139. if (argc == 2 && strcmp(argv[1], "reverse") == 0) {
  140. if (fork() == 0)
  141. server();
  142. else
  143. client();
  144. }
  145. /* both client and server are children */
  146. if (argc == 2 && strcmp(argv[1], "children") == 0) {
  147. if (fork() == 0)
  148. server();
  149. if (fork() == 0)
  150. client();
  151. wait(NULL);
  152. wait(NULL);
  153. }
  154. msgctl(msqid, IPC_RMID, NULL);
  155. return 0;
  156. }