C++多线程强制终⽌详细
⽬录
前⾔:
故事的起因来源于我在优化他⼈c++源码的时候,想通过多线程的⽅式提升程序的运算效率,主要存在以下需求和难点:
多个线程并⾏跑模型,看哪个模型跑的快,跑出来后结束其他线程,线程间独⽴运⾏⽆通信过程
源码模型很复杂,函数调⽤较多,不好改动,因此不太适合通过信号或标志进⾏通信终⽌
线程结束的⼏种⽅式:
线程函数的return返回(建议):这种退出线程的⽅式是最安全的,在线程函数return返回后, 会清理函数内申请的类对象, 即调⽤这些对象的析构函数.。然后会⾃动调⽤ _endthreadex()函数来清理 _beginthreadex()函数申请的资源(主要是创建的tiddata对象)。
同⼀个进程或另⼀个进程中的线程调⽤TerminateThread函数(应避免使⽤该⽅法):TerminateThread
能够撤消任何线程,其中hThread参数⽤于标识被终⽌运⾏的线程的句柄。当线程终⽌运⾏时,它的退出代码成为你作为dwExitCode参数传递的值。同时,线程的内核对象的使⽤计数也被递减。注意TerminateThread函数是异步运⾏的函数,也就是说,它告诉系统你想要线程终⽌运⾏,但是,当函数返回时,不能保证线程被撤消。如果需要确切地知道该线程已经终⽌运⾏,必须调
⽤WaitForSingleObject或者类似的函数,传递线程的句柄。
通过调⽤ExitThread函数:线程将⾃⾏撤消(最好不使⽤该⽅法)。该函数将终⽌线程的运⾏,并导致操作系统清除该线程使⽤的所有操作系统资源。但是,C++资源(如C++类对象)将不被析构。
ExitProcess和TerminateProcess函数也可以⽤来终⽌线程的运⾏(应避免使⽤该⽅法):
选项2和3可能会导致内存泄漏,实际上,没有任何语⾔或操作系统可以为你提供异步突然终⽌线程的便利,且不会警告你不要使⽤它们。所有这些执⾏环境都强烈建议开发⼈员,甚⾄要求在协作或同步线程终⽌的基础上构建多线程应⽤程序。
现有的线程结束函数,包括linux系统的pthread.h中的pthread_exit()和pthread_cancel(),windows系统的win32.h中
的ExitThread()和TerminateThread(),也就是说,C++没有提供kill掉某个线程的能⼒,只能被动地等
待某个线程的⾃然结束,析构函数~thread()也不能停⽌线程,析构函数只能在线程静⽌时终⽌线程joinable,对于连接/分离的线程,析构函数根本⽆法终⽌线程。
要终⽌与OS /编译器相关的函数的线程,我们需要知道如何从C++获取本机线程数据类型std::thread。幸运的是,在调⽤或之
前std::thread提供了⼀个API native_handle()以获取线程的本机句柄类型。并且可以将此本地句柄传递给本地OS线程终⽌函数,例如join() detach() pthread_cancel()。
以下代码⽤于显⽰std::thread::native_handle(),std::thread::get_id()并pthread_lf()返回相同的代码pthread_t来处理Linux / GCC的
C++线程
#include <mutex>中南大学外国语学院
#include <iostream>
#include <chrono>
#include <cstring>
#include <pthread.h>
std::mutex iomutex;
void f(int num)
{
std::this_thread::sleep_for(std::chrono::conds(1));
渐进式延迟退休std::lock_guard<std::mutex> lk(iomutex);
std::cout << "Thread " << num << " pthread_t " << pthread_lf() << std::endl;
}
明天的事
int main()
{
std::thread t1(f, 1), t2(f, 2);
/
/t1.join(); t2.join(); ----------------pos 1
//t1.detach(); t2.detach(); -------------pos 2
std::cout << "Thread 1 thread id " << t1.get_id() << std::endl;
std::cout << "Thread 2 thread id " << t2.get_id() << std::endl;
std::cout << "Thread 1 native handle " << t1.native_handle() << std::endl;
std::cout << "Thread 2 native handle " << t2.native_handle() << std::endl;
t1.join(); t2.join();
//t1.detach(); t2.detach();
}
上海四金
运⾏后可以得到结果
$ g++ -Wall -std=c++11 cpp_thread_pthread -o cpp_thread_pthread -pthread -lpthread
$ ./cpp_thread_pthread
Thread 1 thread id 140109390030592
Thread 2 thread id 140109381637888
Thread 1 native handle 140109390030592
Thread 2 native handle 140109381637888
Thread 1 pthread_t 140109390030592
腿部肌肉怎么练Thread 2 pthread_t 140109381637888
uncommentpos 1或者pos 2后,即调⽤join()或之后detach(),C++线程会丢失本机句柄类型的信息$ ./cpp_thread_pthread
Thread 1 pthread_t 139811504355072
Thread 2 pthread_t 139811495962368
Thread 1 thread id thread::id of a non-executing thread
Thread 2 thread id thread::id of a non-executing thread
Thread 1 native handle 0
Thread 2 native handle 0
因此,要有效地调⽤本机线程终⽌函数(例如pthread_cancel),需要在调⽤std::thread::join()时或之前保存本机句柄std::thread::detach()。这样,始终可以使⽤有效的本机句柄终⽌线程。
class Foo {远景规划>放大图片
public:
void sleep_for(const std::string &tname, int num)
{
prctl(PR_SET_NAME,tname.c_str(),0,0,0);
sleep(num);
}
void start_thread(const std::string &tname)
{
std::thread thrd = std::thread(&Foo::sleep_for, this, tname, 3600);
tm_[tname] = thrd.native_handle();
thrd.detach();
std::cout << "Thread " << tname << " created:" << std::endl;杭椒牛柳家常的做法
}
void stop_thread(const std::string &tname)
{
ThreadMap::const_iterator it = tm_.find(tname);
if (it != tm_.end()) {
pthread_cancel(it->cond);
tm_.era(tname);
std::cout << "Thread " << tname << " killed:" << std::endl;
}
}
private:
typedef std::unordered_map<std::string, pthread_t> ThreadMap;
ThreadMap tm_;
};
int main()
{
Foo foo;
std::string keyword("test_thread");
std::string tname1 = keyword + "1";
std::string tname2 = keyword + "2";
// create and kill thread 1
foo.start_thread(tname1);
foo.stop_thread(tname1);
// create and kill thread 2
foo.start_thread(tname2);
foo.stop_thread(tname2);
return 0;
}
结果是:
$ g++ -Wall -std=c++11 kill_cpp_thread -o kill_cpp_thread -pthread -lpthread
$ ./kill_cpp_thread
Thread test_thread1 created:
30332 30333 pts/5 00:00:00 test_thread1
Thread test_thread1 killed:
Thread test_thread2 created:
30332 30340 pts/5 00:00:00 test_thread2
Thread test_thread2 killed:
当然,条件允许的话最好还是使⽤返回或信号的⽅式终⽌线程,这样也符合安全可信的要求。
到此这篇关于C++多线程强制终⽌详细的⽂章就介绍到这了,更多相关C++多线程强制终⽌内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!