msg_send.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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. int server (void)
  24. {
  25. struct timeval tv1, tv2;
  26. int msqid;
  27. struct msgbuf buf;
  28. size_t len;
  29. int i;
  30. if ((msqid = msgget(key, mode == SERIAL ? 0600|IPC_CREAT : 0)) < 0) {
  31. perror("msgget");
  32. exit(1);
  33. }
  34. gettimeofday(&tv1, NULL);
  35. for (i = 0 ; i < TEST_TIMES ; i++) {
  36. buf.mtype = (i % TEST_TYPES) + 1;
  37. if (msgsnd(msqid, &buf, PAYLOAD_SIZE, 0) < 0) {
  38. perror("msgsnd");
  39. exit(1);
  40. }
  41. #ifndef DO_BENCH
  42. printf("Message: \"%s\" sent\n", buf.mtext);
  43. #endif
  44. }
  45. gettimeofday(&tv2, NULL);
  46. if (mode == PARALLEL) {
  47. char byte = 0;
  48. close(pipefds[0]);
  49. write(pipefds[1], &byte, 1);
  50. close(pipefds[3]);
  51. read(pipefds[2], &byte, 1);
  52. }
  53. printf("time spent on %d msgsnd: %llu microsecond\n",
  54. TEST_TIMES,
  55. (tv2.tv_sec * 1000000ull + tv2.tv_usec) -
  56. (tv1.tv_sec * 1000000ull + tv1.tv_usec));
  57. if (mode != IN_PROCESS)
  58. exit(0);
  59. }
  60. /* client always sends messages */
  61. int client (void)
  62. {
  63. struct timeval tv1, tv2;
  64. int msqid;
  65. struct msgbuf buf;
  66. int i, ret;
  67. if (mode == PARALLEL) {
  68. char byte = 0;
  69. close(pipefds[1]);
  70. read(pipefds[0], &byte, 1);
  71. }
  72. if ((msqid = msgget(key, 0)) < 0) {
  73. perror("msgget");
  74. exit(1);
  75. }
  76. gettimeofday(&tv1, NULL);
  77. for (int i = 0 ; i < TEST_TIMES ; i++) {
  78. int type = (i % TEST_TYPES) + 1;
  79. if ((ret = msgrcv(msqid, &buf, PAYLOAD_SIZE, type, 0)) < 0) {
  80. perror("msgrcv");
  81. exit(1);
  82. }
  83. #ifndef DO_BENCH
  84. buf.mtext[ret] = 0;
  85. printf("Client received: \"%s\"\n", buf.mtext);
  86. #endif
  87. }
  88. gettimeofday(&tv2, NULL);
  89. if (mode == PARALLEL) {
  90. char byte = 0;
  91. close(pipefds[2]);
  92. write(pipefds[3], &byte, 1);
  93. }
  94. printf("time spent on %d msgrcv: %llu microsecond\n",
  95. TEST_TIMES,
  96. (tv2.tv_sec * 1000000ull + tv2.tv_usec) -
  97. (tv1.tv_sec * 1000000ull + tv1.tv_usec));
  98. if (mode != IN_PROCESS)
  99. exit(0);
  100. }
  101. int main (int argc, char ** argv)
  102. {
  103. int msqid;
  104. key = rand();
  105. #ifndef DO_BENCH
  106. printf("Msg queue key: 0x%8x\n", key);
  107. #endif
  108. /* server run first and client run later */
  109. if (argc == 2 && strcmp(argv[1], "serial") == 0) {
  110. mode = SERIAL;
  111. if (fork() == 0)
  112. server();
  113. wait(NULL);
  114. if (fork() == 0)
  115. client();
  116. wait(NULL);
  117. msgctl(msqid, IPC_RMID, NULL);
  118. return 0;
  119. }
  120. if ((msqid = msgget(key, 0600|IPC_CREAT)) < 0) {
  121. perror("msgget");
  122. exit(1);
  123. }
  124. /* server run first and client run later (in the same process) */
  125. if (argc == 2 && strcmp(argv[1], "in-process") == 0) {
  126. mode = IN_PROCESS;
  127. server();
  128. client();
  129. msgctl(msqid, IPC_RMID, NULL);
  130. return 0;
  131. }
  132. pipe(&pipefds[0]);
  133. pipe(&pipefds[2]);
  134. /* server to be the parent and client to be the child */
  135. if (argc == 1) {
  136. if (fork() == 0)
  137. client();
  138. else
  139. server();
  140. }
  141. /* client to be the parent and server to be the child */
  142. if (argc == 2 && strcmp(argv[1], "reverse") == 0) {
  143. if (fork() == 0)
  144. server();
  145. else
  146. client();
  147. }
  148. /* both client and server are children */
  149. if (argc == 2 && strcmp(argv[1], "children") == 0) {
  150. if (fork() == 0)
  151. server();
  152. if (fork() == 0)
  153. client();
  154. wait(NULL);
  155. wait(NULL);
  156. }
  157. msgctl(msqid, IPC_RMID, NULL);
  158. return 0;
  159. }