greeting.pthread.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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. /* greetings.c -- greetings program
  4. *
  5. * Send a message from all processes with rank != 0 to process 0. Process 0
  6. * prints the messages received.
  7. *
  8. * Input: none. Output: contents of messages received by process 0.
  9. *
  10. * See Chapter 3, pp. 41 & ff in PPMPI. */
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <sys/types.h>
  14. #include <pthread.h>
  15. #include <unistd.h>
  16. #include <stdlib.h>
  17. #define MAX_THREAD 1000
  18. typedef struct
  19. {
  20. int id;
  21. int nproc;
  22. } parm;
  23. char message[100]; /* storage for message */
  24. pthread_mutex_t msg_mutex = PTHREAD_MUTEX_INITIALIZER;
  25. int token = 0;
  26. void* greeting(void *arg)
  27. {
  28. parm *p = (parm *) arg;
  29. int id = p->id;
  30. int i;
  31. if (id != 0)
  32. {
  33. /* Create message */
  34. while (1)
  35. {
  36. pthread_mutex_lock(&msg_mutex);
  37. if (token == 0)
  38. {
  39. sprintf(message, "Greetings from process %d!", id);
  40. token++;
  41. pthread_mutex_unlock(&msg_mutex);
  42. break;
  43. }
  44. pthread_mutex_unlock(&msg_mutex);
  45. sleep(1);
  46. }
  47. /* Use strlen+1 so that '\0' gets transmitted */
  48. } else
  49. { /* my_rank == 0 */
  50. for (i = 1; i < p->nproc; i++)
  51. {
  52. while (1)
  53. {
  54. pthread_mutex_lock(&msg_mutex);
  55. if (token == 1)
  56. {
  57. printf("%s\n", message);
  58. token--;
  59. pthread_mutex_unlock(&msg_mutex);
  60. break;
  61. }
  62. pthread_mutex_unlock(&msg_mutex);
  63. sleep(1);
  64. }
  65. }
  66. }
  67. return NULL;
  68. }
  69. int main(int argc, char *argv[])
  70. {
  71. int my_rank; /* rank of process */
  72. int dest; /* rank of receiver */
  73. int tag = 0; /* tag for messages */
  74. pthread_t *threads;
  75. pthread_attr_t pthread_custom_attr;
  76. parm *p;
  77. int n, i;
  78. if (argc != 2)
  79. {
  80. printf("Usage: %s n\n where n is no. of thread\n", argv[0]);
  81. return 1;
  82. }
  83. n = atoi(argv[1]);
  84. if ((n < 1) || (n > MAX_THREAD))
  85. {
  86. printf("The no of thread should between 1 and %d.\n", MAX_THREAD);
  87. return 1;
  88. }
  89. threads = (pthread_t *) malloc(n * sizeof(*threads));
  90. pthread_attr_init(&pthread_custom_attr);
  91. p=(parm *)malloc(sizeof(parm)*n);
  92. /* Start up thread */
  93. for (i = 0; i < n; i++)
  94. {
  95. p[i].id = i;
  96. p[i].nproc = n;
  97. pthread_create(&threads[i], &pthread_custom_attr, greeting, (void *)(p+i));
  98. }
  99. /* Synchronize the completion of each thread. */
  100. for (i = 0; i < n; i++)
  101. {
  102. pthread_join(threads[i], NULL);
  103. }
  104. free(p);
  105. } /* main */