semaphore.h 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /*
  2. * Copyright (c) 2016 The ZLToolKit project authors. All Rights Reserved.
  3. *
  4. * This file is part of ZLToolKit(https://github.com/xia-chu/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 <atomic>
  21. #include <mutex>
  22. #include <condition_variable>
  23. using namespace std;
  24. namespace toolkit {
  25. class semaphore {
  26. public:
  27. explicit semaphore(size_t initial = 0) {
  28. #if defined(HAVE_SEM)
  29. sem_init(&_sem, 0, initial);
  30. #else
  31. _count = 0;
  32. #endif
  33. }
  34. ~semaphore() {
  35. #if defined(HAVE_SEM)
  36. sem_destroy(&_sem);
  37. #endif
  38. }
  39. void post(size_t n = 1) {
  40. #if defined(HAVE_SEM)
  41. while (n--) {
  42. sem_post(&_sem);
  43. }
  44. #else
  45. unique_lock<mutex> lock(_mutex);
  46. _count += n;
  47. if(n == 1){
  48. _condition.notify_one();
  49. }else{
  50. _condition.notify_all();
  51. }
  52. #endif
  53. }
  54. void wait() {
  55. #if defined(HAVE_SEM)
  56. sem_wait(&_sem);
  57. #else
  58. unique_lock<mutex> lock(_mutex);
  59. while (_count == 0) {
  60. _condition.wait(lock);
  61. }
  62. --_count;
  63. #endif
  64. }
  65. private:
  66. #if defined(HAVE_SEM)
  67. sem_t _sem;
  68. #else
  69. size_t _count;
  70. mutex _mutex;
  71. condition_variable_any _condition;
  72. #endif
  73. };
  74. } /* namespace toolkit */
  75. #endif /* SEMAPHORE_H_ */