C++ 多线程之线程管理函数

简介: 这篇文章介绍了C++中多线程编程的几个关键函数,包括获取线程ID的`get_id()`,延时函数`sleep_for()`,线程让步函数`yield()`,以及阻塞线程直到指定时间的`sleep_until()`。

写在前面:

好像突然发现没有啥写的, 那就不写了。哈哈哈~~~

1. 获取线程 id 函数 get_id()的使用

该函数在命名空间std::this_thread下。作用是获取当前线程的id。

#include <iostream>
#include <thread>
using namespace std;

//No.1 get_id() 获取线程id
void threadFunc() {
    cout << "get_id() 子线程id: " << this_thread::get_id() << endl;
    using namespace this_thread;
    cout << "get_id() 子线程id: " << get_id() << endl;
}
void test01() {
    cout << "主线程id: " << this_thread::get_id() << endl;
    thread t1(threadFunc);
    t1.join();
}
int main() {

    test01();
    return 0;
}

2. 延时函数sleep_for()的使用

该函数在命名空间std::this_thread下。作用是延时。

#include <iostream>
#include <thread>
#include <chrono>
using namespace std;

//No.2 sleep_for() 延时函数
void threadSleepFor() {
    using namespace this_thread;
    cout << "子线程id: " << get_id()  << " 线程启动!" << endl;

    this_thread::sleep_for(2s); //文本重载方式 延时两秒

    sleep_for(chrono::seconds(2)); //延时两秒

    using namespace chrono;
    sleep_for(seconds(2));

    cout << "子线程id: " << get_id() << " 线程结束!" << endl;
}
void test02() {
    thread t2(threadSleepFor);
    t2.join();
}

int main() {

    test02();
    return 0;
}

线程启动后, 在线程处理函数中,会延时一段时间。延时结束后,继续执行未执行完的线程处理函数。

3. 线程让步函数yield()的使用

该函数在命名空间std::this_thread下。作用是让当前线程让步,让操作系统执行另一个线程。

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

//No.3 yield()    线程让步(让线程放弃执行, 让操作系统调用另一个线程执行)
void threadYield(chrono::milliseconds duration) {   //间隔时间ms
    using namespace this_thread;
    cout << "yield: 子线程id: " << get_id() << " 线程开始!" << endl;

    //使用高精度时钟获取当前时间
    auto startTime = chrono::high_resolution_clock::now();
    auto endTime = startTime + duration;
    do {
        //线程让步
        yield();
    } while (chrono::high_resolution_clock::now() < endTime);

    cout << "yield: 子线程id: " << get_id() << " 线程结束!" << endl;
}
//chrono::microseconds 微秒
void test03() {
    thread at[5];
    //线程1让步 5 秒
    at[0] = thread(threadYield, chrono::milliseconds(5000));
    //其余四个线程让步 0 秒(每隔一秒创建一个线程)
    for (int i = 1; i < 5; i++) {
        this_thread::sleep_for(1s);
        at[i] = thread(threadYield, chrono::milliseconds(0));
    }
    for (auto& th : at) {
        th.join();
    }
}
int main() {

    system("color F0");
    test03();

    return 0;
}

由下面的运行结果可知,第一个(线程id为12304)的 线程会等待5秒(线程让步5秒),此时操作系统会执行下面的四个线程,待5秒之后,让步的线程(线程id为12304)的线程处理函数继续向下执行。

4. 阻塞线程函数sleep_until()的使用

该函数在命名空间std::this_thread下。作用是阻塞当前线程,直到sleep_time溢出。

#include <iostream>
#include <thread>
#include <chrono>
#include <iomanip>
#include <windows.h>
using namespace std;

void threadFunc() {
    cout << "get_id() 子线程id: " << this_thread::get_id() << endl;
    using namespace this_thread;
    cout << "get_id() 子线程id: " << get_id() << endl;
}

//No.4 sleep_until() 阻塞当前执行线程 直到sleep_time溢出
void threadSleepUntil() {
    cout << "sleep_until: 子线程id: " << this_thread::get_id() << " 线程开始!" << endl;

    time_t tt = chrono::system_clock::to_time_t(chrono::system_clock::now());
    tm* ptm = new tm;
    localtime_s(ptm, &tt);
    cout << put_time(ptm, "%X") << endl;
    //设置sleep_time为5秒
    for (int i = 0; i < 5; i++)
    {
        ++ptm->tm_sec;
    }
    if (ptm != nullptr) {
        this_thread::sleep_until(chrono::system_clock::from_time_t(mktime(ptm)));
    }
    cout << put_time(ptm, "%X") << endl;

    cout << "sleep_until: 子线程id: " << this_thread::get_id() << " 线程结束!" << endl;
}
void test04() {
    thread t1(threadSleepUntil);
    this_thread::sleep_for(1s);
    thread t2(threadFunc);
    t1.join();
    t2.join();
}
int main() {
    system("color F0");
    test04();

    return 0;
}

由下面的运行结果可知,线程t1会进入阻塞状态(sleep_time)阻塞5秒钟,然后t2线程会执行,5秒后t1线程退出阻塞状态,继续执行t1线程的线程处理函数。

相关文章
|
27天前
|
缓存 安全 C++
C++无锁队列:解锁多线程编程新境界
【10月更文挑战第27天】
37 7
|
27天前
|
消息中间件 存储 安全
|
2月前
|
存储 并行计算 安全
C++多线程应用
【10月更文挑战第29天】C++ 中的多线程应用广泛,常见场景包括并行计算、网络编程中的并发服务器和图形用户界面(GUI)应用。通过多线程可以显著提升计算速度和响应能力。示例代码展示了如何使用 `pthread` 库创建和管理线程。注意事项包括数据同步与互斥、线程间通信和线程安全的类设计,以确保程序的正确性和稳定性。
|
2月前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
20 3
|
2月前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
19 2
|
2月前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
31 2
|
2月前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
34 1
|
2月前
|
安全 Java 开发者
Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用
本文深入解析了Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用。通过示例代码展示了如何正确使用这些方法,并分享了最佳实践,帮助开发者避免常见陷阱,提高多线程程序的稳定性和效率。
38 1
|
2月前
|
Java
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件成立时被唤醒,从而有效解决数据一致性和同步问题。本文通过对比其他通信机制,展示了 `wait()` 和 `notify()` 的优势,并通过生产者-消费者模型的示例代码,详细说明了其使用方法和重要性。
28 1
|
2月前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。