多线程问题

1.linux和windows环境下终止C++11 thread问题

目前我们创建线程大部分用的都是基于C++11中的thread,但是C++中为了各种安全问题并没有提供结束线程的方法,但是我们有时候会用到杀死C++11创建的线程,这时候就要根据我们所处的开发环境来判断了。

1.windows

在C++11中,可以使用std::thread的joinable()函数来检查线程是否可被杀死,如果线程可被杀死,可以使用std::thread的成员函数join()来等待线程执行完毕。然而,在Windows下,C++11标准库并没有提供直接的方法来杀死线程,因此我们需要使用Windows API TerminateThread来实现

cpp 复制代码
#include <iostream>
#include <thread>
#include <windows.h>

// 线程函数
void threadFunction()
{
    // 模拟一些工作
    for (int i = 0; i < 10; ++i)
    {
        std::cout << "Working..." << std::endl;
        Sleep(1000); // 线程休眠1秒
    }
}

int main()
{
    std::thread t(threadFunction); // 创建线程
    
    // 等待用户输入
    std::cout << "Press ENTER to kill the thread." << std::endl;
    std::cin.get();
    
    // 检查线程是否可被杀死
    if (t.joinable())
    {
        // 使用Windows API来终止线程
        TerminateThread(t.native_handle(), 0);
        
        // 等待线程执行完毕
        t.join();
        
        std::cout << "Thread killed." << std::endl;
    }
    
    return 0;
}

2.Linux

使用pthread_cancel

cpp 复制代码
#include <iostream>
#include <thread>
#include <chrono>
#include <pthread.h>

using namespace std;

void foo() {
	size_t x = 0;
	while (1) {
		cout << ++x << endl;
		this_thread::sleep_for(chrono::milliseconds(100));
	}
}

int main() {
	std::cerr << "1、先杀死再join\n";
	{
		thread t(foo);
		this_thread::sleep_for(chrono::seconds(1));
		cout << "t.joinable() = " << t.joinable() << endl;
		pthread_cancel(t.native_handle());
		cout << "after cancelling, t.joinable() = " << t.joinable() << endl;
		t.join();
	}
	cout << "The thread is destructed\n\n";
	this_thread::sleep_for(chrono::seconds(1));

	std::cerr << "2、先detach再杀死\n";
	{
		thread t(foo);
		pthread_t id = t.native_handle();
		t.detach();
		cout << "detached\n";
		this_thread::sleep_for(chrono::seconds(1));
		cout << "t.joinable() = " << t.joinable() << endl;
		pthread_cancel(id);
	}
	cout << "The thread is destructed\n\n";
	this_thread::sleep_for(chrono::seconds(1));

	std::cerr << "3、thread对象的析构函数不会杀死线程\n";
	{
		thread t(foo);
		t.detach();
		this_thread::sleep_for(chrono::seconds(1));
	}
	this_thread::sleep_for(chrono::seconds(1));

	return 0;
}

来源:C++11 终止一个thread对象表示的线程

tips:

在linux环境下,使用pthread_create创建线程时,如果想要将类的成员函数变成线程函数,需要将类的成员函数声明为static,而使用C++11的thread创建的线程则没有这个限制。

cpp 复制代码
void A::add(void *data)
{
    A *obj = static_cast<A *>(data);
    cout << "sum" << obj->num1 + obj->num2 << endl;
    cout << "sum::" << num1 + num2 << endl;
}
int A::num(int a, int b)
{
    num1 = a;
    num2 = b;
    pthread_t myThread;
    // int ret = pthread_create(&myThread, nullptr, A::add, this);
    std::thread t(&A::add, this, this);
    t.join();
}

注意两个this的区别:
第一个 this 表示当前对象本身的指针,它用于指定要调用的成员函数 &A::add 所在的对象。
第二个 this 是作为函数参数传递给 A::add 的参数。这表示在调用 &A::add 函数时,将当前对象的指针作为参数传递给 A::add 函数。

相关推荐
郝学胜-神的一滴11 分钟前
Linux进程与线程控制原语对比:双刃出鞘,各显锋芒
linux·服务器·开发语言·数据结构·c++·程序人生
青岛少儿编程-王老师26 分钟前
CCF编程能力等级认证GESP—C++2级—20251227
java·开发语言·c++
javachen__39 分钟前
341-十道经典程序设计题目
数据结构·c++·算法
wregjru40 分钟前
【C++】2.6 红黑树及其实现(附代码)
开发语言·c++
zgl_200537791 小时前
ZGLanguage 解析SQL数据血缘 之 提取select语句中的源表名
大数据·数据库·c++·数据仓库·sql·数据库开发·etl
Sereinc.Y1 小时前
【移动机器人运动规划(ROS)】03_ROS话题-服务-动作
c++·动态规划·ros·slam
@卞3 小时前
从零实现一个高并发内存池(1)--- 项目介绍
c++
wjlnew3 小时前
c++中的内存管理:栈,堆及RALL机制
c++
无限进步_4 小时前
【C语言】用队列实现栈:数据结构转换的巧妙设计
c语言·开发语言·数据结构·c++·链表·visual studio
千里马-horse5 小时前
TypedArrayOf
开发语言·javascript·c++·node.js·napi