引言
当讨论现代编程语言的特性时,C++11无疑是一个不容忽视的里程碑。在前一篇文章中,我们深入探讨了Lambda表达式在C++11中的引入和应用。本文将继续探索C++11的强大功能,具体而言,我们这篇文章将聚焦于线程库和其中的thread类。
线程在多任务处理中起着至关重要的作用,它们允许程序同时执行多个任务,从而提高效率和响应速度。在C++11之前,线程的处理相对复杂且容易出错。然而,在C++11中引入的thread类为我们带来了更加便捷和安全的线程管理方式。让我们一起深入研究C++11线程库中的thread类,探索多线程编程的无限潜力吧!
一、thread类的简单介绍
thread的官方文档
thread类是C++11引入的一个重要特性,它位于<thread>头文件中,并提供了一种简单而强大的方式来实现多线程编程。
使用thread类,我们可以轻松地创建和管理线程。通过创建thread对象,我们可以指定要执行的线程函数,并传递所需的参数。一旦线程对象被创建,我们可以使用它的成员函数来控制线程的生命周期,如启动线程、等待线程完成、检查线程是否运行等。
⭕以下是thread类的一些常用成员函数:
函数名 | 功能 |
构造函数 | 用于创建线程对象,并指定要执行的函数或可调用对象。 |
start() | 启动线程的执行,使线程进入就绪状态并开始运行。 |
join() | 阻塞当前线程,直到被调用的线程执行完毕。通常用于等待线程的结束,并获取线程的返回值(如果有)。 |
detach() | 将线程对象设置为分离状态,使得线程无法被其他线程join(),并在执行完毕后自动释放资源。 |
get_id() | 返回线程的ID,用于唯一标识一个线程。 |
joinable() | 查询线程是否可执行,即查询线程是否已经启动但未被join()。 |
hardware_concurrency() | 返回当前系统支持的最大线程数,通常与CPU核心数相同。 |
🚨注意:以上仅列举了thread类的部分常用成员函数,还有其他一些成员函数和静态成员函数可供我们使用。同时,在使用这些成员函数时,我们需要注意线程安全性和同步机制,以避免出现竞态条件和数据不一致的问题。
二、线程函数详细介绍
1. start() 函数
start()函数通常是由线程对象调用的,用于开始执行一个新线程。
(1)头文件
start()函数在C++标准库的<thread>头文件中进行声明。
(2)函数原型
start()函数的函数原型如下:
void start();
2. join() 函数
在C++标准库中,std::thread类提供了join()函数用于等待一个线程的结束并回收资源。
(1)头文件
join()函数在C++标准库的<thread>头文件中进行声明。
(2)函数原型
join()函数的函数原型如下:
void join();
3. detach() 函数
detach()函数是std::thread类提供的一个成员函数,用于将线程与std::thread对象分离,使其成为一个独立的线程,并在后台运行。
(1)头文件
detach()函数在C++标准库的<thread>头文件中进行声明。
(2)函数原型
detach()函数的函数原型如下:
void detach();
(3)使用示例
下面是一个使用std::thread及其detach()函数的示例:
#include <iostream> #include <thread> void thread_func() { std::cout << "Hello from new thread!" << std::endl; } int main() { std::thread t(thread_func); // 创建一个新线程,并指定线程函数 t.detach(); // 分离新线程 std::cout << "Hello from main thread!" << std::endl; return 0; }
在上述示例中,我们首先创建一个std::thread对象t,并将一个线程函数thread_func作为参数传递给构造函数。然后,我们通过调用t.detach()函数将新线程与std::thread对象分离。最后,主线程输出“Hello from main thread!”。
在运行上述示例时,将会看到如下输出:
Hello from main thread! Hello from new thread!
由于我们在主线程中调用了t.detach()函数,新线程成为一个独立的线程,并在后台运行。因此,在输出“Hello from main thread!”之后,新线程才会输出“Hello from new thread!”。
4. get_id() 函数
get_id()函数是std::thread类提供的一个成员函数,用于获取与std::thread对象相关联的线程的ID。
(1)头文件
get_id()函数在C++标准库的<thread>头文件中进行声明。
(2)函数原型
get_id()函数的函数原型如下:
std::thread::id get_id() const noexcept;
(3)使用示例
下面是一个使用std::thread及其get_id()函数的示例:
#include <iostream> #include <thread> void thread_func() { std::cout << "Thread ID: " << std::this_thread::get_id() << std::endl; } int main() { std::thread t(thread_func); // 创建一个新线程,并指定线程函数 std::cout << "Main thread ID: " << std::this_thread::get_id() << std::endl; t.join(); // 等待新线程结束 return 0; }
在上述示例中,我们首先创建一个std::thread对象t,并将一个线程函数thread_func作为参数传递给构造函数。然后,我们通过调用t.join()函数等待新线程结束。在新线程的线程函数中,我们输出线程的ID。在主线程中,我们也输出主线程的ID。
在运行上述示例时,将会看到如下输出:
Main thread ID: 140102324408064 Thread ID: 140102234146560
由于我们在主线程中调用了std::this_thread::get_id()函数和新线程中的get_id()函数,分别获取了主线程和新线程的ID。可以看到,两个线程的ID是不同的。
5. joinable() 函数
joinable()函数是std::thread类提供的一个成员函数,用于检查与std::thread对象关联的线程是否可以被join或detach。
(1)头文件
joinable()函数在C++标准库的<thread>头文件中进行声明。
(2)函数原型
joinable()函数的函数原型如下:
bool joinable() const noexcept;
(3)参数解释
joinable()函数没有参数。调用该函数时,将返回一个bool类型的值,表示与std::thread对象相关联的线程是否可以被join或detach。
(4)返回值
joinable()函数返回值类型为bool。如果与std::thread对象相关联的线程可以被join或detach,则返回true;否则返回false。
(5)使用示例
下面是一个使用std::thread及其joinable()函数的示例:
#include <iostream> #include <thread> void thread_func() { std::cout << "Hello from new thread!" << std::endl; } int main() { std::thread t(thread_func); // 创建一个新线程,并指定线程函数 std::cout << "Is thread joinable? " << t.joinable() << std::endl; // 输出true t.join(); // 等待新线程结束 std::cout << "Is thread joinable? " << t.joinable() << std::endl; // 输出false return 0; }
在上述示例中,我们首先创建一个std::thread对象t,并将一个线程函数thread_func作为参数传递给构造函数。然后,我们通过调用t.joinable()函数检查与std::thread对象关联的线程是否可以被join或detach。在新线程结束之前,该函数返回true。在调用t.join()函数等待新线程结束后,该函数返回false。
三、std::this_thread命名空间
C++11引入了std::this_thread命名空间,其中包含了一些与当前线程相关的函数和属性。这些函数和属性以全局函数或静态成员函数的形式提供。
⭕以下是std::this_thread命名空间下的一些常用函数:
函数名 | 功能 |
std::this_thread::get_id() | 获取当前线程的ID,返回一个std::thread::id对象。 |
std::this_thread::sleep_for() | 使当前线程休眠一段指定的时间。接受一个std::chrono::duration作为参数,表示休眠的时间间隔。 |
std::this_thread::yield() | 暂时放弃当前线程的执行,允许其他线程运行。调用yield()后,当前线程可能会被重新调度执行,也可能继续让其他线程执行。 |
🚨注意:这些函数是与当前线程直接相关的,而不是用于创建或管理线程的类。
温馨提示
感谢您对博主文章的关注与支持!另外,我计划在未来的更新中持续探讨与本文相关的内容,会为您带来更多关于C++以及编程技术问题的深入解析、应用案例和趣味玩法等。请继续关注博主的更新,不要错过任何精彩内容!
再次感谢您的支持和关注。期待与您建立更紧密的互动,共同探索C++、算法和编程的奥秘。祝您生活愉快,排便顺畅!