admin 管理员组

文章数量: 887154


2024年1月18日发(作者:redhat虚拟机linux)

c++结束线程方法

在 C++ 中,可以通过多线程来实现并发处理任务的功能。但是,如果不及时退出或删除线程,会导致一些不必要的资源浪费,从而可能导致应用程序出现崩溃等问题。因此,在应用程序中使用线程时,有必要了解如何合理地结束线程。本文将对 C++ 中结束线程的方法进行详细的介绍。

一、线程的声明和创建

首先,我们需要了解线程的声明和创建方式。C++ 11 标准中,可以使用 std::thread

类来声明和创建线程,该类定义如下:

class thread {

public:

// 构造函数,创建新线程

template

explicit thread(Function&& f, Args&&... args);

// 析构函数,销毁线程

~thread();

// 判断线程是否可用

bool joinable() const noexcept;

// 等待线程执行结束

void join();

// 分离线程,不等待线程执行结束即可销毁线程对象

void detach();

// 获取线程 ID

std::thread::id get_id() const noexcept;

// 交换线程对象

void swap(thread& x) noexcept;

// 禁用拷贝构造函数和赋值运算符

thread(const thread&) = delete;

thread& operator=(const thread&) = delete;

};

在使用 std::thread 类创建线程时,需要传递一个函数对象和若干参数。该函数对象将作为线程的入口点,在新线程上执行。

在 C++ 中,有多种方法来结束线程。下面介绍几种常见的方法。

1. 使用 join() 函数等待线程执行完毕

当线程执行完毕后,可以通过调用 std::thread 类的 join() 函数来等待线程执行结束。

std::thread t1(foo); // 创建线程 t1

(); // 等待线程 t1 执行结束

join() 函数会一直阻塞当前线程,直到被调用的线程结束为止。如果调用 join()

函数时被调用的线程已经结束,join() 函数将立即返回。

需要注意的是,如果线程对象已经分离或销毁,调用 join() 函数会导致程序崩溃。

2. 使用 detach() 函数分离线程

和 join() 函数不同,detach() 函数将使线程和线程对象分离,当前线程不会等待被调用线程执行完毕。一旦线程对象被分离,就无法再次等待该线程执行完毕。

3. 使用 std::atomic_flag 定义线程结束标志

该类型的 test_and_set() 方法,会先测试当前标志,如果标志为真,就返回 true,否则将标志设置为真,然后返回 false。

#include

#include

#include

#include

std::atomic_flag flag = ATOMIC_FLAG_INIT; // 定义结束标志

void foo()

{

while (!_and_set()) { // 循环检测结束标志

std::cout << "Hello, world!n";

std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 休眠 500 毫秒

}

}

在该示例中,while 循环不断检测结束标志 flag,如果标志为真,就退出循环。在主线程休眠 2 秒后,设置标志 flag 为 true,然后等待线程 t1 执行完毕。

std::condition_variable cv; // 定义条件变量

std::mutex mtx; // 定义互斥量

bool done = false; // 定义结束标志

std::promise 可以用来在一个线程中传递值或状态,以便另一个线程在必要时能够得知它,并按照定义的方式进行处理。

下面是一个使用 std::promise 通知线程结束的示例:

void foo(std::shared_ptr> p)

{

std::cout << "Hello, world!n";

p->set_value(); // 设置值

}

在该示例中,线程 foo() 接受一个 std::shared_ptr> 对象作为参数。在该线程中,我们输出一个字符串,并使用该对象的 set_value() 函数通知主线程之前设置的 std::future 对象,表示该线程已经执行完毕。

除了使用 std::atomic_flag 类型外,我们还可以使用 std::atomic 类型来实现线程结束的通知。该类型的构造函数和方法如下:

在该示例中,线程 foo() 会不断输出一个字符串,并在输出后休眠 500 毫秒,直到

done 标志为 true,才退出循环。

7. 使用线程局部存储来结束线程

线程局部存储是一种机制,允许程序在需要时在线程本地存储数据。C++ 中,可以使用 std::thread_local 关键字声明线程局部变量。当线程结束时,线程局部变量自动销毁。

thread_local bool done = false; // 定义线程局部变量

在该示例中,我们定义了一个线程局部变量 done,用于控制线程结束。在 foo() 函数中,只要 done 为 false,就不断输出一个字符串。当 done 变为 true 时,线程局部变量 done 自动销毁,线程结束。

三、小结

本文介绍了 C++ 中结束线程的方法,包括使用 join() 函数等待线程结束、使用

detach() 函数分离线程、使用 std::atomic_flag 、std::condition_variable、std::promise 以及 std::atomic 类型来通知线程结束,以及使用线程局部存储实现线程结束等方法。不同的方法适用于不同的情况,需要根据实际需求选用合适的方法。


本文标签: 线程 结束 函数 执行