Linux C/C++网络编程实战-陈硕-笔记24-dummyload实现原理和代码

在这里插入图片描述
控制CPU使用可以使用脉冲宽度调制,控制CPU一段时间内“忙”和“闲”的比例。

CPU使用率的测量:某段时间内,CPU“忙”所占的比例。
(多核情况下,可以大于 100%)

CPU使用率的控制:通过控制一个测量周期内,CPU“忙”所占时间与总周期时间的占比。

示例说明如何控制CPU使用率:

例如控制CPU使用率在20%。我们需要做的是在一个测量周期T = 100s内,使CPU忙的时间占 Tx=20s , 空闲时间占 Ty = 80s。这样,在一个T周期内,CPU所占时间占比总的时间 = Tx / T = 20%
在这里插入图片描述

这样的做法使得CPU在一个T周期内的利用率并不均匀。最好的做法就是,将一个T的周期均分为若干个小的周期Tn,在每个小周期内依然按照 Tx : Ty 的比例进行CPU的“忙”/“闲”切换。
在这里插入图片描述

根据以上的方式我们可以调节CPU的占空比,从而在某种意义上而言我们可以控制CPU的使用率。

例如,我们要控制 60% 的使用率,那么它的波形应该如下图所示,其中波峰代表cpu busy loop,波谷代表cpu等待,这样我们在宏观上通过调整波峰与波谷的比例,将各自的时间比例维持在6:4 便可以得到一个这样的矩形波。
在这里插入图片描述

同样的,如果我们以一个小的Tn为单位,动态的调整波峰与波谷的时间比例,例如T0 { T x : T y = 5 : 5 } , T1 { Tx : Ty = 6 : 4 } , T0 { Tx : Ty = 7 : 3 } , . . . . . 那么我们得到的将是一个锯齿波形图。

代码

地址:
https://github.com/Anita-Mul/muduo-chenshuo/blob/master/examples/procmon/dummyload.cc

  • dummyload
    #include <muduo/base/Atomic.h>
    #include <muduo/base/Condition.h>
    #include <muduo/base/CurrentThread.h>
    #include <muduo/base/Mutex.h>
    #include <muduo/base/Thread.h>
    #include <muduo/base/Timestamp.h>
    #include <muduo/net/EventLoop.h>
    
    #include <boost/ptr_container/ptr_vector.hpp>
    
    #include <math.h>
    #include <stdio.h>
    
    using namespace muduo;
    using namespace muduo::net;
    
    int g_cycles = 0;
    int g_percent = 82;
    AtomicInt32 g_done;
    bool g_busy = false;
    MutexLock g_mutex;
    Condition g_cond(g_mutex);
    
    double busy(int cycles)
    {
      double result = 0;
      for (int i = 0; i < cycles; ++i)
      {
        result += sqrt(i) * sqrt(i+1);
      }
      return result;
    }
    
    double getSeconds(int cycles)
    {
      Timestamp start = Timestamp::now();
      busy(cycles);
      return timeDifference(Timestamp::now(), start);
    }
    
    void findCycles()
    {
      g_cycles = 1000;
      while (getSeconds(g_cycles) < 0.001)
        g_cycles = g_cycles + g_cycles / 4;  // * 1.25
      printf("cycles %d\n", g_cycles);
    }
    
    void threadFunc()
    {
      while (g_done.get() == 0)
      {
        {
        MutexLockGuard guard(g_mutex);
        while (!g_busy)
          g_cond.wait();
        }
        busy(g_cycles);
      }
      printf("thread exit\n");
    }
    
    // this is open-loop control
    void load(int percent)	// 设定CPU使用率
    {
      percent = std::max(0, percent);
      percent = std::min(100, percent);
    
      // Bresenham's line algorithm
      int err = 2*percent - 100;
      int count = 0;
    
      for (int i = 0; i < 100; ++i)
      {
        bool busy = false;
        if (err > 0)
        {
          busy = true;
          err += 2*(percent - 100);
          ++count;
          // printf("%2d, ", i);
        }
        else
        {
          err += 2*percent;
        }
    
        {
        MutexLockGuard guard(g_mutex);
        g_busy = busy;
        g_cond.notifyAll();
        }
    
        CurrentThread::sleepUsec(10*1000); // 10 ms
      }
      assert(count == percent);
    }
    
    void fixed()	// 固定的cpu使用率
    {
      while (true)
      {
        load(g_percent);	// 对于cpu使用率固定,每次load相同的percent
      }						// g_percent 全局变量,且峰值由参数指定
    }
    
    void cosine()		// 	余弦曲线
    {
      while (true)
        for (int i = 0; i < 200; ++i)	// 以200s为一个周期,以1s为一个小周期
        {	// 通过余弦曲线获得当前cpu使用率数值,通过时间改变当前CPU使用率数值,可以得到一个连续的曲线
          int percent = static_cast<int>((1.0 + cos(i * 3.14159 / 100)) / 2 * g_percent + 0.5);
          load(percent);	// 设定CPU使用率
        }
    }
    
    void sawtooth()
    {
      while (true)
        for (int i = 0; i <= 100; ++i)
        {
          int percent = static_cast<int>(i / 100.0 * g_percent);
          load(percent);
        }
    }
    
    int main(int argc, char* argv[])
    {
      if (argc < 2)
      {
        printf("Usage: %s [fctsz] [percent] [num_threads]\n", argv[0]);
        return 0;
      }
    
      printf("pid %d\n", getpid());		// 打印 pid ,以便procmon程序监控
      findCycles();
    
      g_percent = argc > 2 ? atoi(argv[2]) : 43;
      int numThreads = argc > 3 ? atoi(argv[3]) : 1;
      boost::ptr_vector<Thread> threads;
      for (int i = 0; i < numThreads; ++i)
      {
        threads.push_back(new Thread(threadFunc));
        threads.back().start();
      }
    
      switch (argv[1][0])	// 处理参数
      {
        case 'f':		// 固定cpu使用率到某个范围,例如固定cpu使用率到30%
        {
          fixed();
        }
        break;
    
        case 'c':		// 余弦曲线
        {
          cosine();
        }
        break;
    
        case 'z':	// 锯齿波形
        {
          sawtooth();
        }
        break;
    
        // TODO: square and triangle waves
    
        default:
        break;
      }
    
      g_done.getAndSet(1);
      {
      MutexLockGuard guard(g_mutex);
      g_busy = true;
      g_cond.notifyAll();
      }
      for (int i = 0; i < numThreads; ++i)
      {
        threads[i].join();
      }
    }
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux多线程服务端编程是指在Linux操作系统上开发多线程的服务器程序。而muduo C网络库(陈硕)是一个专门用于开发高性能网络服务器的C++库。 muduo C网络库是在muduo网络库的基础上进行了移植和改造,使其支持使用C语言进行开发。它提供了一系列高效的网络编程组件和工具,以简化多线程网络服务器的开发过程。 muduo C网络库基于Reactor模式,并且在设计上遵循了高并发、低延迟、高性能的原则。它可以处理上千个并发连接,并且具有稳定性和可靠性。 通过muduo C网络库,开发人员能够方便地实现多线程网络服务器。它提供了事件处理循环、网络IO、定时器、线程池等基本组件,可以有效地管理和处理网络连接。此外,muduo C网络库还提供了高效的多线程同步和协调机制,以支持服务器的并发处理能力。 使用muduo C网络库,开发人员可以简化网络服务器的编程过程,同时提高服务器的性能和扩展性。相比于手动处理底层网络细节,使用muduo C可以更加专注于业务逻辑的实现,提升开发效率。 总结来说,Linux多线程服务端编程使用muduo C网络库可以轻松开发高性能的网络服务器。它提供了丰富的组件和工具,满足了开发人员高并发、低延迟、高性能的需求。无论是大型互联网应用还是分布式系统,muduo C网络库都是一个可靠的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值