• C++多线程编程(2):四种线程管理方法


    文章首发于我的个人博客:欢迎大佬们来逛逛

    线程管理

    有一个this_thread的名称空间中定义了许多的线程管理方法:

    • get_id:获取当前线程id
    • sleep_for:当前线程休眠一段时间
    • sleep_for:当前线程休眠,直到某个时间点之后结束休眠
    • yield:当前线程立刻被抛弃,释放CPU时间片

    get_id

    获取当前线程id,每个线程的id都是唯一的,并且也可以获取主线程的id:

    //获取线程Id
    void threadID() {
    	std::cout << "Id: " << std::this_thread::get_id() << '\n';
    }
    
    • 1
    • 2
    • 3
    • 4

    sleep_for

    chrono库提供了许多关于时间的操作,在我们接下来的介绍中需要用到。

    当前线程休眠一段时间,其中一段时间是你自己给出的。

    实际上调用这个函数会立刻使得线程从运行态转为阻塞状态,并且休眠一段时间。

    位于阻塞态会让出当前的CPU资源,因此可以使得其他线程使用他让出的CPU资源,提高资源的利用率。

    线程的五种状态:创建,就绪,运行,阻塞,终止

    函数原型如下:

    • chrono::duration:表示一个时间段。
    void sleep_for(const chrono::duration<...>& durationTime)
    
    • 1

    具体如何传参?

    std::this_thread::sleep_for(std::chrono::seconds(2));  // 休眠两秒
    std::this_thread::sleep_for(std::chrono::microseconds(2000)); //休眠两千毫秒
    
    • 1
    • 2

    还有minutes,hours等等。

    //sleep_for延迟函数
    void testSleep_for() {
    	std::cout << "子线程sleep_for: \n";
    	std::this_thread::sleep_for(std::chrono::seconds(2));
    	std::cout << "子线程sleep_for结束: \n";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    sleep_until

    该函数与上面的函数类似,只不过他接受一个时间点,上面的sleep_for是一个时间段

    void sleep_until(const chrono::time_point<...>& _Abs_time)
    
    • 1

    对于chrono如何表示一个时间点**time_point** 有以下方法:

    • system_clock:获取系统时间

    • steady_clock: 表示稳定时间间隔,即不随系统时间修改而变化的时间间隔。

    • high_resolution_clock: 实际上就是上一种

      using high_resolution_clock = steady_clock;
      
      • 1

    如何获取当前时间?

    使用now()函数

    以下三种根据情况使用,都可以作为sleep_until的参数。

    std::chrono::high_resolution_clock::now();
    std::chrono::system_clock::now();
    std::chrono::steady_colck::now();
    
    • 1
    • 2
    • 3

    具体应用:

    使得每次打印间隔两秒的时间间隔,如下我们构造了一个时间点

    实际上与sleep_for类似,只不过sleep_for表示一个时间段,sleep_until表示到…为止,是一个时间点。

    std::cout << "子线程Sleep_untild: \n";
    	for (int i = 1; i <= 10; i++) {
    		auto startTime = std::chrono::steady_clock::now();
    		std::this_thread::sleep_until(startTime+std::chrono::seconds(2));
    		std::cout << "i= " << i << '\n';
    	}
    std::cout << "子线程Sleep_untild结束: \n";
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    yield

    该函数表示立刻抛弃(立刻停止)此线程,释放CPU时间片,并且立刻使得该线程从运行转到就绪状态

    注意虽然抛弃了此线程,释放了CPU的资源,但是它仍然会参与到下一轮的线程CPU时间片的争夺中,也就是说我调用了这个函数函数,为什么感觉没有什么用呢?实际上这是一个概率问题。

    案例:

    每执行一次循环,让该线程主动放弃 CPU 资源重新和其他线程再次抢夺 CPU 时间片,如果其他线程抢到了 CPU 时间片就可以执行相应的任务了。

    否则容易出现其他线程没有机会执行的困难。

    void testYield2(int id) {
    	for (int i = 1; i <= 1000; i++) {
    		std::cout << "id: " <<id << ": " << i << '\n';
    		std::this_thread::yield();
    	}
    }
    
    ...
    std::thread t3(testYield2, 1);
    std::thread t4(testYield2, 2);
    t3.join();
    t4.join();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

  • 相关阅读:
    优雅停止 SpringBoot 服务,拒绝 kill -9 暴力停止
    手摸手带你撸一个拖拽效果
    两个对象比较内部数据的变化,并返回对应key数组
    Python ‘list‘ object is not callable错误
    8、ByteBuffer(方法演示2(allocate堆内存和allocateDirect直接内存))
    [C++初阶]一些类的选择题
    HCIA网络课程第三周作业
    AntDesignBlazor示例——暗黑模式
    Android的六大布局详解
    django安装到运行,简单的注册登录
  • 原文地址:https://blog.csdn.net/jj6666djdbbd/article/details/134490785