21xrx.com
2024-12-22 16:21:23 Sunday
登录
文章检索 我的文章 写文章
如何在C++中强制停止线程?
2023-07-05 07:18:18 深夜i     --     --
C++ 线程 停止 强制 取消

在线程编程中,强制停止线程是一个非常关键的话题。在进行一些繁重的任务或是 IO 操作时,强制停止线程如果不得当,就可能导致数据的损坏以及程序不稳定等问题。C++ 中提供了一些机制来帮助开发者在必要的情况下强制停止线程。

1. 使用 std::thread::join

std::thread 类的 join() 方法可用于等待线程完成并防止主线程退出,这在绝大多数情况下是比较稳妥的一种停止方式。当然,前提是你的线程代码中可随时让线程退出。

举例:我们在主线程中通过 std::thread 类创建了一个子线程,然后通过 join() 方法等待它完成并终止。


#include <iostream>

#include <thread>

void doWork()

{

  for (int i = 0; i < 10; ++i)

  {

    std::cout << "Working...\n";

    std::this_thread::sleep_for(std::chrono::milliseconds(100));

  }

}

int main()

{

  std::thread t(doWork);

  t.join();

  std::cout << "Done.\n";

  return 0;

}

在上面的代码中,我们通过 std::thread 类创建了一个线程 t,并在主线程中调用其 join() 方法等待线程 t 完成并终止。

2. 使用 std::thread::detach

std::thread 类的 detach() 方法可以将该线程与当前线程分离,使其成为独立的线程并在后台运行,与当前线程无关。使用 detach() 方法通常不必担心线程的生命周期问题,但也不建议在需要线程结束后才执行某些操作的情况下使用。


#include <iostream>

#include <thread>

void doWork()

{

  for (int i = 0; i < 10; ++i)

  {

    std::cout << "Working...\n";

    std::this_thread::sleep_for(std::chrono::milliseconds(100));

  }

}

int main()

{

  std::thread t(doWork);

  t.detach();

  std::cout << "Done.\n";

  return 0;

}

在上面的代码中,我们通过 std::thread 类创建了一个线程 t,并在主线程中调用其 detach() 方法分离线程 t,并使其成为独立的线程。

无论是 join() 还是 detach(),它们都是一个相对安全的线程停止方案,但是它们都需要线程本身去自行管理线程终止。如果想要强制停止线程,就必须采用一些更加激进的手段。

3. 使用 std::thread::hardware_concurrency

std::thread 类有一个内置的硬件并发级别函数,std::thread::hardware_concurrency ,通过这个函数我们可以得到硬件环境中支持的最大线程数。当然,也可以在创建线程时手动指定数量。


#include <iostream>

#include <thread>

void doWork() {

  for (int i = 0; i < 10; ++i) {

    std::cout << "Working...\n";

    std::this_thread::sleep_for(std::chrono::milliseconds(100));

  }

}

int main()

{

  int maxThreads = std::thread::hardware_concurrency();

  std::cout << "Max threads: " << maxThreads << std::endl;

  std::thread threads[maxThreads];

  for (int i = 0; i < maxThreads; i++){

    threads[i] = std::thread(doWork);

  }

  for (int i = 0; i < maxThreads; i++) {

    threads[i].join();

  }

  std::cout << "Done.\n";

  return 0;

}

在上面的代码中,我们通过 std::thread::hardware_concurrency 函数拿到了当前硬件支持的最大线程数,随后我们创建了同样数量的线程并执行,最后再在主线程中等待它们全部完成。

4. 使用 std::terminate

在 C++11 中,std::terminate 是一个在异常处理程序无法处理异常时调用的函数。在某些情况下,可以使用 std::terminate 函数去强制停止某个线程的执行。但这样做很危险,因为它可能会导致数据损坏,甚至是对应用程序的崩溃。

如果要使用 std::terminate 函数,可以启动一个 std::thread 线程并在其中调用 std::terminate 函数。


#include <iostream>

#include <thread>

#include <exception>

void doWork()

{

  std::cout << "Working..." << std::endl;

  throw std::exception();

}

int main()

{

  try

  {

    std::thread t(doWork);

    t.join();

  }

  catch (std::exception&)

  {

    std::terminate();

  }

  std::cout << "Done.\n";

  return 0;

}

在上面的代码中,我们在子线程的循环执行中抛出了一个 std::exception 异常,然后在主线程中尝试通过 std::terminate 函数来强行结束当前线程的执行。但我们不建议大家轻易尝试使用 std::terminate,因为它的副作用是未知的。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复