歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 利用POSIX互斥鎖和條件變量實現的信號量

利用POSIX互斥鎖和條件變量實現的信號量

日期:2017/3/1 11:17:57   编辑:Linux編程

利用POSIX互斥鎖、條件變量,和內存映射文件,實現的信號量機制,用於進程間的同步。

  1. /* sem.h */
  2. struct semaphore
  3. {
  4. pthread_mutex_t lock;
  5. pthread_cond_t nonzero;
  6. unsigned count;
  7. };
  8. typedef struct semaphore semaphore_t;
  9. semaphore_t* semaphore_create(char *semaphore_name);
  10. semaphore_t* semaphore_open(char *semaphore_name);
  11. void semaphore_post(semaphore_t *semap);
  12. void semaphore_wait(semaphore_t *semap);
  13. void semaphore_close(semaphore_t *semap);
  14. /* sem.c */
  15. #include <sys/types.h>
  16. #include <sys/stat.h>
  17. #include <sys/mman.h>
  18. #include <fcntl.h>
  19. #include <pthread.h>
  20. #include "sem.h"
  21. semaphore_t* semaphore_create(char *semaphore_name)
  22. {
  23. int fd = open(semaphore_name, O_RDWR | O_CREAT | O_EXCL, 0666);
  24. if (fd < 0) return (NULL);
  25. (void) ftruncate(fd, sizeof(semaphore_t));
  26. pthread_mutexattr_t psharedm;
  27. pthread_condattr_t psharedc;
  28. (void) pthread_mutexattr_init(&psharedm);
  29. (void) pthread_mutexattr_setpshared(&psharedm, PTHREAD_PROCESS_SHARED);
  30. (void) pthread_condattr_init(&psharedc);
  31. (void) pthread_condattr_setpshared(&psharedc, PTHREAD_PROCESS_SHARED);
  32. semaphore_t* semap = (semaphore_t *) mmap(NULL,
  33. sizeof(semaphore_t),
  34. PROT_READ | PROT_WRITE,
  35. MAP_SHARED,
  36. fd,
  37. 0);
  38. close (fd);
  39. (void) pthread_mutex_init(&semap->lock, &psharedm);
  40. (void) pthread_cond_init(&semap->nonzero, &psharedc);
  41. // 我覺得應該給個大於零的初值
  42. semap->count = 0;
  43. return (semap);
  44. }
  45. semaphore_t* semaphore_open(char *semaphore_name)
  46. {
  47. int fd = open(semaphore_name, O_RDWR, 0666);
  48. if (fd < 0) return (NULL);
  49. semaphore_t* semap = (semaphore_t *) mmap(NULL,
  50. sizeof(semaphore_t),
  51. PROT_READ | PROT_WRITE,
  52. MAP_SHARED,
  53. fd,
  54. 0);
  55. close (fd);
  56. return (semap);
  57. }
  58. void semaphore_post(semaphore_t *semap)
  59. {
  60. pthread_mutex_lock(&semap->lock);
  61. // 計數為零,說明可能有線程已經阻塞在該條件變量上
  62. if (semap->count == 0)
  63. {
  64. pthread_cond_signal(&semapx->nonzero);
  65. }
  66. semap->count++;
  67. pthread_mutex_unlock(&semap->lock);
  68. }
  69. void semaphore_wait(semaphore_t *semap)
  70. {
  71. pthread_mutex_lock(&semap->lock);
  72. // 計數為零,說明已無資源,等待
  73. while (semap->count == 0)
  74. {
  75. pthread_cond_wait(&semap->nonzero, &semap->lock);
  76. }
  77. semap->count--;
  78. pthread_mutex_unlock(&semap->lock);
  79. }
  80. void semaphore_close(semaphore_t *semap)
  81. {
  82. munmap((void *) semap, sizeof(semaphore_t));
  83. }
Copyright © Linux教程網 All Rights Reserved