msg_send.c 4.0 KB

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