c++11 chrono库知识点(二)及条件变量示范代码

修正上篇的high_resolution_clock的描述

一。chrono部分

chrono::duration的代码实现

    template <class _Rep, class _Period>
    class duration { // represents a time duration
    public:
        using rep    = _Rep;
        using period = typename _Period::type;

_Rep参数表示传入的 时间单位 的类型,可以为float, int, long long等等,比如传入表示0.3倍个某个时间单位
_Period参数代表了 时间单位,可以为微秒,毫秒,秒,分钟,小时 甚至是其它自定义的单位。

比如:

using d10_seconds = chrono::duration<float, std::ratio<1, 10>>;        //1/10秒的时间单位,类型是float

stl库的stedy_clock代码

    struct steady_clock { // wraps QueryPerformanceCounter
        using rep                       = long long;
        using period                    = nano;
        using duration                  = nanoseconds;
        using time_point                = _CHRONO time_point<steady_clock>;
        static constexpr bool is_steady = true;

        _NODISCARD static time_point now() noexcept { // get current time
            const long long _Freq = _Query_perf_frequency(); // doesn't change after system boot
            const long long _Ctr  = _Query_perf_counter();
            static_assert(period::num == 1, "This assumes period::num == 1.");
            // Instead of just having "(_Ctr * period::den) / _Freq",
            // the algorithm below prevents overflow when _Ctr is sufficiently large.
            // It assumes that _Freq * period::den does not overflow, which is currently true for nano period.
            // It is not realistic for _Ctr to accumulate to large values from zero with this assumption,
            // but the initial value of _Ctr could be large.
            const long long _Whole = (_Ctr / _Freq) * period::den;
            const long long _Part  = (_Ctr % _Freq) * period::den / _Freq;
            return time_point(duration(_Whole + _Part));
        }
    };

    using high_resolution_clock = steady_clock;

#if _HAS_CXX20
    // [time.duration.io]
....

high_resolution_clock可以安全使用,就是个别名而已。

修正上篇的high_resolution_clock的描述

学习std::ratio、chrono::duration、chrono::duration_cast以及

time_point、system_clock、steady_clock等的示范代码:

#include <ratio>
#include <algorithm>
#include <numeric>

static void slow_motion()
{
	static int a[]{ 1,2,3,4,5,6,7,8,9,10,11,12 };
	{
	}
}
void pre_chrono()
{
	{
		using p1 = std::ratio<1, 100>;
		using p2 = std::ratio<1, 10>;

		using p = std::ratio_add<p1, p2>;
		cout << "ratio " << p::num << "/" << p::den << "\n";
	}

	//duration, duration_cast
	{
		//一下三种写法,效果相同,睡眠100ms.
		std::this_thread::sleep_for(std::chrono::milliseconds(100));
		// or   milli即为ratio<1, 1000>千分之一默认单位。(默认单位为秒)
		std::this_thread::sleep_for(std::chrono::duration<long long, std::milli>(100));
		// or   
		std::this_thread::sleep_for(std::chrono::duration<long long, std::ratio<1, 1000> >(100));

		//仿造std::milli写法,可构造个新单位,比如:3/10秒
		using second_3_10 = chrono::duration<long long, std::ratio<3, 10>>;		//使用long long 是与chrono::seconds配合一致。
		chrono::seconds val = chrono::duration_cast< chrono::seconds >(second_3_10(4));
		cout << "4个3/10秒val = " << val.count() << " 个秒\n";

		using three_seconds = chrono::duration<float, std::ratio<3, 1> > ;
		using one_tenth_seconds = chrono::duration<float, std::ratio<1, 10> > ;
		three_seconds s = chrono::duration_cast<three_seconds>(one_tenth_seconds(3));
		cout << "3个1/10秒val = " << s.count() << " 个3秒\n";

		using seven_seconds = chrono::duration<float, std::ratio<7, 1>>;		//7秒的单位
		using d10_seconds = chrono::duration<float, std::ratio<1, 10>>;		//1/10的单位
		d10_seconds s1 = chrono::duration_cast<d10_seconds>(seven_seconds(2));
		d10_seconds s2 = chrono::duration_cast<d10_seconds>(seven_seconds(0.33));
		d10_seconds s3 = s1 + s2;
		s3 ++;
		cout << "2个七秒 == " << s1.count() << " 个1/10秒。   0.33个七秒 == " << s2.count() << " 个1/10秒\n";
		cout << "sum = " << s3.count() << "\n";
		int kk = 0;

		using n2_d5 = chrono::duration<float, std::ratio<2, 5>>;		//宏定义个2/5秒的单位。接下来看看一个2/5秒等于多少个毫秒
		using n1_d1000 = chrono::duration<float, ratio<1, 1000>>;
		n1_d1000 t1 = chrono::duration_cast<n1_d1000>(n2_d5(1));
		n1_d1000 t2 = chrono::duration_cast<n1_d1000>(n2_d5(3));

		cout << "一个2/5秒 == " << t1.count() << "\n";
		cout << "三个2/5秒 == " << t2.count() << "\n";
		kk = 0;
	}

	//time_point
	//system_clock, steady_clock,  high_resolution_clock
	{
		vector<double> val(100'000'000, 0.4);
		auto t_start = chrono::steady_clock::now();		//time_point
		double val_sum = std::accumulate(val.begin(), val.end(), 1.0);
		auto t_end = chrono::high_resolution_clock::now();
		
		chrono::duration<double, std::ratio<1, 1000>> msec = t_end - t_start;
		chrono::duration<double, std::ratio<1, 10>> d10sec = t_end - t_start;
		cout << "耗时:" << msec.count() << " 毫秒\n";
		cout << "耗时:" << d10sec.count() << " 个1/10秒\n";
	}

	chrono::time_point<chrono::system_clock, chrono::seconds> tp(chrono::seconds(120));		//120s
	int tick_seconds = tp.time_since_epoch().count();
	cout << "从纪元开始过了(epoch) " << tick_seconds << "s\n";

	time_t tt = chrono::system_clock::to_time_t(tp);
	char szbuff[64];
	ctime_s(szbuff, sizeof(szbuff), &tt);
	cout << szbuff << "\n";
}

二。条件变量学习的代码示范

10个消费者,一个生产者的代码

/// <summary>
/// C.以下是10个消费者线程,一个生产者线程
/// </summary>
int cargo_2 = 0;
const int CNT = 10;

struct is_judge2_ext {
	int m_i = 0;
	is_judge2_ext(int iv) :m_i(iv) {};
	bool operator()() {
		return cargo_2 == m_i;
	}
};

std::once_flag of_flag;
void consume3(int iIdx)
{
	std::call_once(of_flag, [&]() {
		cout << "only once!" << iIdx << "\n";
		});

	for (int i = 0; i < 3; i++) {
		std::unique_lock<std::mutex> lck(mtx2);
		{
			if (i) {
				std::cout << "wait " << iIdx << std::endl;
			}
			_cond2.wait(lck, is_judge2_ext(iIdx));
		}
		
		cout << "consume   " << iIdx << endl;

		cargo_2 = 0;
	}
}

//#define MULTI_PRODUCE

void test_cond3()		//接口,同时也作为生产者
{
	std::thread _thd[CNT];
	for (int i = 0; i < CNT; i++) {
		_thd[i] = std::thread(consume3, i + 1);
	}

#ifdef MULTI_PRODUCE
#else
	for (int j = 0; j < 3; j++) {
		for (int i = 0; i < CNT; i++) {
			int times = 0;
			while (cargo_2) {
				std::this_thread::yield();
				times++;
			}

			{
				std::unique_lock<std::mutex> lck(mtx2);
				cargo_2 = CNT - i;

				std::cout << "produce   " << cargo_2 << "  " << times << std::endl;
			}

			//条件变量通知无须持有锁的!!!
			_cond2.notify_all();
		}

		cout << "prod over!\n\n";
	}
#endif

	for (auto& _iter: _thd) {
		_iter.join();
	}

	int k = 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值