C++ —— std::this_thread 命名空间


C++11引入了 多线程支持,其中 std::this_thread是一个 命名空间,它提供了操作当前线程的一系列函数,本文主要讲述常用的一些函数。

std::this_thread::sleep_for(duration)

作用:使线程休眠指定时间,参数是时间长度
示例代码:

#include <iostream>
#include <thread>
#include <unistd.h> // sleep() 函数要用
using namespace std;

void func (int n, const string& s) {
    for (int i = 1; i <= 3; i++) {
        cout << "No." << i << " n = " << n << ", s = " << s << endl;
        this_thread::sleep_for(chrono::seconds(1)); // 休眠1秒
        // sleep(1); // 两个函数效果一样
    }
}

int main () {
    thread t1(func, 1, "hello"); // 用函数func创建线程t1
    thread t2(func, 2, "~ hi ~"); // 用函数func创建线程t2

    t1.join(); // 等待线程t1退出,回收它的资源
    t2.join(); // 等待线程t2退出,回收它的资源
}

std::this_thread::sleep_until(time_point)

作用:使当前线程直到某个时间点再继续运行,可实现定时任务,参数是时间点(不常用)。

std::this_thread::get_id()

作用:获取当前线程的id
多线程的程序中,每一个线程都有自己的id,这个id不重复,用于识别线程。
示例代码:

#include <iostream>
#include <thread>
#include <unistd.h>
using namespace std;

void func (int n, const string& s) {
    // this_thread::get_id()放在func函数中,表示线程t1和t2的id。
    cout << "子线程 this_thread::get_id() = " << this_thread::get_id() << endl;
    for (int i = 1; i <= 3; i++) {
        cout << "No." << i << " n = " << n << ", s = " << s << endl;
        this_thread::sleep_for(chrono::seconds(1));
    }
}

int main () {
    thread t1(func, 1, "hello"); // 用函数func创建线程t1和线程t2
    thread t2(func, 2, "~ hi ~");
    
    cout << "主线程 this_thread::get_id() = " << this_thread::get_id() << endl;
    // this_thread表示当前线程
    // 把this_thread::get_id()放在main函数中,表示主线程的id。
    cout << "t1.get_id() = " << t1.get_id() << endl;
    // 返回线程对象t1、t2对应的线程id
    cout << "t2.get_id() = " << t2.get_id() << endl;

    t1.join(); // 等待线程t1和t2退出,回收它们的资源
    t2.join();
}

编译命令:g++ -o 可执行文件名 源代码.cpp -pthread
相同的程序,每次运行,产生的线程id不一样
运行结果:

主线程 this_thread::get_id() = 140228786366272
t1.get_id() = 140228786362112
子线程 this_thread::get_id() = 子线程 this_thread::get_id() = t2.get_id() = 140228777969408
140228777969408
No.1 n = 2, s = ~ hi ~
140228786362112
No.1 n = 1, s = hello
No.2 n = 2, s = ~ hi ~
No.2 n = 1, s = hello
No.3 n = 2, s = ~ hi ~
No.3 n = 1, s = hello

std::this_thread::yield()

作用:让当前线程放弃执行,主动让出自己已经抢到的CPU时间片,让其他线程有机会运行。它仅仅是一个建议,并不保证一定会发生上下文切换,其效果依赖于操作系统调度器的实现。
不需要参数,也不返回值。只需直接调用即可。

void worker() {
    for (int i = 0; i < 10; i++) {
        std::cout << "线程 " << std::this_thread::get_id() << " 正在运行,迭代:" << i << std::endl;
        // 提示调度器让出当前线程的CPU时间给其他线程
        std::this_thread::yield();
    }
}

std::thread::swap()

std::thread对象不能拷贝不能赋值,但是可以交换移动
std::thread类中的swap()方法用于交换两个线程对象的内部状态,也就是说,它交换了两个线程对象所管理的线程执行句柄。
示例代码:

#include <iostream>
#include <thread>
#include <unistd.h>
using namespace std;

void func (int n, const string& s) {
    cout << "子线程 this_thread::get_id() = " << this_thread::get_id() << endl;
    for (int i = 1; i <= 3; i++) {
        cout << "No." << i << " n = " << n << ", s = " << s << endl;
        this_thread::sleep_for(chrono::seconds(1));
    }
}

int main () {
    thread t1(func, 1, "hello");
    thread t2(func, 2, "~ hi ~");
    
    cout << "主线程 this_thread::get_id() = " << this_thread::get_id() << endl;

    cout << "t1.get_id() = " << t1.get_id() << endl;
    cout << "t2.get_id() = " << t2.get_id() << endl;
	
	t1.swap(t2);
	
	cout << "====================" << endl;
    cout << "t1.get_id() = " << t1.get_id() << endl;
    cout << "t2.get_id() = " << t2.get_id() << endl;

    t1.join();
    t2.join();
}

运行效果:

主线程 this_thread::get_id() = 139699887392576
t1.get_id() = 139699887388416
t2.get_id() = 139699878995712
====================
t1.get_id() = 139699878995712
t2.get_id() = 139699887388416
子线程 this_thread::get_id() = 139699887388416
No.1 n = 1, s = hello
子线程 this_thread::get_id() = 139699878995712
No.1 n = 2, s = ~ hi ~
No.2 n = 2, s = ~ hi ~
No.2 n = 1, s = hello
No.No.3 n = 2, s = 3~ hi ~ n =
1, s = hello

感谢浏览

C++ 中,“TLS”一般指两种完全不同的概念: 1. **传输层安全 (Transport Layer Security)**:这是网络安全协议,用于保护在网络上传输的数据。它并不是直接属于C++语言特性的一部分,而是可以在C++程序中通过第三方库(例如 OpenSSL 或 Boost.Asio)来实现和使用的。 2. **线程本地存储 (Thread Local Storage, TLS)**:这是一种编程技术,允许每个线程拥有独立的变量副本。这有助于避免多线程环境下共享资源的竞争条件问题。从 C++11 标准起,C++ 内置了对线程局部存储的支持,使用 `thread_local` 关键字可以声明一个具有线程生命周期的对象或静态持续时间对象。 对于第二种情况——即作为线程本地存储机制的 TLS,在现代 C++ 编程中有多种应用方式: - 使用 `thread_local` 关键字定义全局、命名空间级别的变量或者是静态成员变量; - 对于函数内部的静态变量也可以添加此关键字使其变为每线程独有的实例; ```cpp #include <iostream> #include <thread> // 定义一个 thread_local 变量 thread_local int tls_var = 0; void print_tls() { std::cout << "Thread ID: " << std::this_thread::get_id() << ", Value of tls_var: " << tls_var++ << '\n'; } int main() { // 创建两个新线程 auto thd1 = std::make_unique<std::thread>(print_tls); auto thd2 = std::make_unique<std::thread>(print_tls); // 等待它们结束 if(thd1->joinable()) thd1->join(); if(thd2->joinable()) thd2->join(); return 0; } ``` 这个例子展示了如何创建和管理简单的线程局部整型值,并演示了每个线程将会有自己独特的计数值。 --- 关于您提到的具体是指哪种含义,请进一步澄清以便我能提供更多针对性的信息!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值