Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

test_semaphore.cpp 2.2KB

před 6 měsíci
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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. #include <csignal>
  11. #include <atomic>
  12. #include "Util/TimeTicker.h"
  13. #include "Util/logger.h"
  14. #include "Thread/threadgroup.h"
  15. #include "Thread/semaphore.h"
  16. using namespace std;
  17. using namespace toolkit;
  18. #define MAX_TASK_SIZE (1000 * 10000)
  19. semaphore g_sem;//信号量
  20. atomic_llong g_produced(0);
  21. atomic_llong g_consumed(0);
  22. //消费者线程
  23. void onConsum() {
  24. while (true) {
  25. g_sem.wait();
  26. if (++g_consumed > g_produced) {
  27. //如果打印这句log则表明有bug
  28. ErrorL << g_consumed << " > " << g_produced;
  29. }
  30. }
  31. }
  32. //生产者线程
  33. void onProduce() {
  34. while(true){
  35. ++ g_produced;
  36. g_sem.post();
  37. if(g_produced >= MAX_TASK_SIZE){
  38. break;
  39. }
  40. }
  41. }
  42. int main() {
  43. //初始化log
  44. Logger::Instance().add(std::make_shared<ConsoleChannel>());
  45. Ticker ticker;
  46. thread_group thread_producer;
  47. for (size_t i = 0; i < thread::hardware_concurrency(); ++i) {
  48. thread_producer.create_thread([]() {
  49. //1个生产者线程
  50. onProduce();
  51. });
  52. }
  53. thread_group thread_consumer;
  54. for (int i = 0; i < 4; ++i) {
  55. thread_consumer.create_thread([i]() {
  56. //4个消费者线程
  57. onConsum();
  58. });
  59. }
  60. //等待所有生成者线程退出
  61. thread_producer.join_all();
  62. DebugL << "生产者线程退出,耗时:" << ticker.elapsedTime() << "ms," << "生产任务数:" << g_produced << ",消费任务数:" << g_consumed;
  63. int i = 5;
  64. while(-- i){
  65. DebugL << "程序退出倒计时:" << i << ",消费任务数:" << g_consumed;
  66. sleep(1);
  67. }
  68. //程序强制退出可能core dump;在程序推出时,生产的任务数应该跟消费任务数一致
  69. WarnL << "强制关闭消费线程,可能触发core dump" ;
  70. return 0;
  71. }