semaphore.h 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /*
  2. * Copyright (c) 2016 The ZLToolKit project authors. All Rights Reserved.
  3. *
  4. * This file is part of ZLToolKit(https://github.com/ZLMediaKit/ZLToolKit).
  5. *
  6. * Use of this source code is governed by MIT license that can be found in the
  7. * LICENSE file in the root of the source tree. All contributing project authors
  8. * may be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef SEMAPHORE_H_
  11. #define SEMAPHORE_H_
  12. /*
  13. * 目前发现信号量在32位的系统上有问题,
  14. * 休眠的线程无法被正常唤醒,先禁用之
  15. #if defined(__linux__)
  16. #include <semaphore.h>
  17. #define HAVE_SEM
  18. #endif //HAVE_SEM
  19. */
  20. #include <mutex>
  21. #include <condition_variable>
  22. namespace toolkit {
  23. class semaphore {
  24. public:
  25. explicit semaphore(size_t initial = 0) {
  26. #if defined(HAVE_SEM)
  27. sem_init(&_sem, 0, initial);
  28. #else
  29. _count = 0;
  30. #endif
  31. }
  32. ~semaphore() {
  33. #if defined(HAVE_SEM)
  34. sem_destroy(&_sem);
  35. #endif
  36. }
  37. void post(size_t n = 1) {
  38. #if defined(HAVE_SEM)
  39. while (n--) {
  40. sem_post(&_sem);
  41. }
  42. #else
  43. std::unique_lock<std::recursive_mutex> lock(_mutex);
  44. _count += n;
  45. if (n == 1) {
  46. _condition.notify_one();
  47. } else {
  48. _condition.notify_all();
  49. }
  50. #endif
  51. }
  52. void wait() {
  53. #if defined(HAVE_SEM)
  54. sem_wait(&_sem);
  55. #else
  56. std::unique_lock<std::recursive_mutex> lock(_mutex);
  57. while (_count == 0) {
  58. _condition.wait(lock);
  59. }
  60. --_count;
  61. #endif
  62. }
  63. private:
  64. #if defined(HAVE_SEM)
  65. sem_t _sem;
  66. #else
  67. size_t _count;
  68. std::recursive_mutex _mutex;
  69. std::condition_variable_any _condition;
  70. #endif
  71. };
  72. } /* namespace toolkit */
  73. #endif /* SEMAPHORE_H_ */