C++多线程常用方法

在 C++ 中,线程相关功能主要通过头文件提供的类和函数来实现,以下是一些常用的线程接口方法和使用技巧:

std::thread类

构造函数:

可以通过传入可调用对象(如函数指针、函数对象、lambda 表达式等)来创建一个线程实例,启动一个新线程去执行对应的任务。例如:

#include <iostream>
#include <thread>

void hello() {
    std::cout << "Hello from thread!" << std::endl;
}

int main() {
    std::thread t(hello);  // 创建线程t并开始执行hello函数
    t.join();  // 等待线程t执行完毕
    return 0;
}

这里std::thread t(hello)就是利用函数指针hello创建线程,新线程会执行hello函数里的代码。

join方法:

用于阻塞当前线程,直到被调用的线程执行完成。比如在上面的main函数中,t.join()会让main线程暂停,等待t线程把hello函数执行完后再继续往下执行。
detach方法

将线程分离,使得线程在后台独立运行,不再与创建它的std::thread对象关联。此后,无法再通过该std::thread对象对这个线程进行控制(比如不能再调用join了)。示例:

#include <iostream>
#include <thread>

void func() {
    // 线程执行的函数内容
    std::cout << "Thread is running independently." << std::endl;
}

int main() {
    std::thread t(func);
    t.detach();  // 分离线程t
    // 主线程继续执行其他操作,不用等待t线程结束
    std::cout << "Main thread continues." << std::endl;
    return 0;
}

线程传参

向线程函数传递参数时,需要保证参数在传递时是有效的,且在被调用函数执行期间持续有效(比如避免传引用指向临时对象等情况)。例如:

#include <iostream>
#include <thread>

void print_num(int num) {
    std::cout << "The number is: " << num << std::endl;
}

int main() {
    int num = 10;
    std::thread t(print_num, num);  // 传递普通变量num作为参数
    t.join();
    return 0;
}

如果要传递类对象等更复杂的情况,要注意拷贝、移动语义等相关问题,确保参数传递的正确性。
线程 ID 获取

可以通过std::this_thread::get_id获取当前线程的线程 ID,或者通过std::thread对象的get_id成员函数获取对应的线程 ID,用于标识和区分不同线程。示例:

#include <iostream>
#include <thread>

void show_thread_id() {
    std::cout << "Thread ID: " << std::this_thread::get_id() << std::endl;
}

int main() {
    std::thread t(show_thread_id);
    std::cout << "Main thread ID: " << std::this_thread::get_id() << std::endl;
    t.join();
    return 0;
}

线程同步相关(例如互斥量等,用于解决多线程访问共享资源冲突问题)

std::mutex(互斥量):

通过lock和unlock方法对共享资源进行加锁和解锁,确保同一时刻只有一个线程能访问被保护的共享资源。例如:

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;
int shared_data = 0;

void increment() {
    for (int i = 0; i < 1000; ++i) {
        mtx.lock();  // 加锁
        shared_data++;
        mtx.unlock();  // 解锁
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);
    t1.join();
    t2.join();
    std::cout << "Shared data value: " << shared_data << std::endl;
    return 0;
}

也可以使用std::lock_guard等 RAII(Resource Acquisition Is Initialization)机制的类来更方便、安全地管理互斥量的生命周期,自动完成加锁和解锁,如:

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;
int shared_data = 0;

void increment() {
    for (int i = 0; i < 1000; ++i) {
        std::lock_guard<std::mutex> guard(mtx);  // 构造时加锁,析构时自动解锁
        shared_data++;
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);
    t1.join();
    t2.join();
    std::cout << "Shared data value: " << shared_data << std::endl;
    return 0;
}

std::condition_variable(条件变量):

常和互斥量配合使用,用于线程间的同步,实现一个线程等待某个条件满足后再继续执行的功能。比如一个线程等待另一个线程修改共享资源达到某个条件后再进行后续操作,典型用法如下:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void wait_for_signal() {
    std::unique_lock<std::mutex> lck(mtx);
    cv.wait(lck, []{ return ready; });  // 等待条件满足(ready为true)
    std::cout << "Received signal and continue." << std::endl;
}

void send_signal() {
    {
        std::lock_guard<std::mutex> lck(mtx);
        ready = true;
    }
    cv.notify_one();  // 通知等待在该条件变量上的一个线程
}

int main() {
    std::thread t1(wait_for_signal);
    std::thread t2(send_signal);
    t1.join();
    t2.join();
    return 0;
}

这些就是 C++ 中线程相关的一些主要接口方法及其基本使用方式,在实际多线程编程中,往往需要综合运用它们来实现高效、正确的并发程序逻辑。

相关推荐
earthzhang2021几秒前
《深入浅出HTTPS》读书笔记(19):密钥
开发语言·网络协议·算法·https·1024程序员节
Cooloooo4 分钟前
Treap树堆【东北大学oj数据结构8-4】C++
开发语言·数据结构·c++
CN.LG9 分钟前
浅谈Java注解之CachePut
java·开发语言·spring
好开心3325 分钟前
2.17、vue的生命周期
java·开发语言·前端·javascript·vue.js·前端框架·ecmascript
PieroPc27 分钟前
Python 写个 《系统信息采集工具》为重装系统做准备。。。
开发语言·python
破局缘36 分钟前
apt文件问题ruby.list文件
开发语言·windows·ruby
晚安~~44 分钟前
社区生活超市系统|Java|SSM|JSP|
java·开发语言·tomcat·maven
Faylynn1 小时前
Python:程序中如何引用环境变量
开发语言·python
小堃学编程1 小时前
Python学习(二)—— 基础语法(上)
开发语言·python
会思想的苇草i1 小时前
JavaScript--原型与原型链
开发语言·前端·javascript·设计模式·原型·原型模式·原型链