C++ 线程操作

C++ 线程操作

概述

线程是 Linux 操作系统中的一种轻量级进程,用于实现并发执行。线程可以共享进程的资源,包括内存、文件句柄等。在 C++ 中,线程操作由标准库提供支持,主要涉及以下几个头文件:

#include     // 线程相关的库
#include      // 互斥量相关的库
#include   // 条件变量相关的库

创建线程
在 C++ 中,使用 std::thread 类创建新线程。创建线程的基本形式为:

std::thread t1(func, args...);

其中 func 是线程执行的函数,args… 是函数的参数列表。

示例:

#include 
#include 

void threadFunc(int n) {
    std::cout << "Thread ID: " << std::this_thread::get_id() 
              << ", n = " << n << std::endl;
}

int main() {
    std::thread t1(threadFunc, 10);
    t1.join();   // join后主线程将会被阻塞,等待线程结束
    return 0;
}

上述代码中,threadFunc 函数被传递给 std::thread 类的构造函数创建一个新线程。线程执行函数中输出线程 ID 和传入的参数值。t1.join() 语句等待线程结束后才会继续执行主线程。

互斥量

在多线程编程中,当多个线程同时访问共享资源时,容易出现竞态条件(Race Condition),导致程序出现不可预期的行为。为了避免这种情况,可以使用互斥量(Mutex)来保护共享资源,确保同一时间只有一个线程可以访问它。

互斥量使用 std::mutex 类实现,常用的方法有:

lock():获得互斥量的锁。
unlock():释放互斥量的锁。
示例:

#include 
#include 
#include 

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

void threadFunc(int n) {
    mtx.lock();   // 获得互斥量的锁
    std::cout << "Thread ID: " << std::this_thread::get_id() 
              << ", n = " << n << std::endl;
    mtx.unlock(); // 释放互斥量的锁
}

int main() {
    std::thread t1(threadFunc, 10);
    std::thread t2(threadFunc, 20);

    t1.join();
    t2.join();
    return 0;
}

在上述代码中,std::mutex 类型的 mtx 对象用于保护 threadFunc 函数中的输出操作,以避免同时输出导致的混乱。

条件变量

在多线程编程中,有时需要让线程等待某个条件满足后再继续执行,这时可以使用条件变量(Condition Variable)来实现。

条件变量使用 std::condition_variable 类实现,常用的方法有:

  • wait(lock, pred):等待条件变量满足。lock 是互斥量,用于保护条件变量; pred 是一个可调用对象,用于判断条件是否满足。
  • notify_one():唤醒一个等待条件变量的线程。
  • notify_all():唤醒所有等待条件变量的线程。

示例:

#include 
#include 
#include 
#include 

std::mutex mtx;  // 定义互斥量
std::condition_variable cv;  // 定义条件变量

bool ready = false;  // 条件变量状态标志

void threadFunc(int n) {
    std::unique_lock<std::mutex> lock(mtx);
    while (!ready) {   // 等待条件变量
        cv.wait(lock);
    }
    std::cout << "Thread ID: " << std::this_thread::get_id() 
              << ", n = " << n << std::endl;
}

int main() {
    std::thread t1(threadFunc, 10);
    std::thread t2(threadFunc, 20);

    // 设置条件变量状态标志
    std::this_thread::sleep_for(std::chrono::seconds(2));
    ready = true;
    cv.notify_all();  // 唤醒所有等待条件变量的线程

    t1.join();
    t2.join();
    return 0;
}

在上述代码中,std::condition_variable 类型的 cv 对象用于实现线程等待条件变量的功能。在 threadFunc 函数中,使用 cv.wait(lock) 等待条件变量。在 main 函数中,先等待一段时间后设置条件变量状态标志 ready 为 true,再通过 cv.notify_all() 唤醒所有等待条件变量的线程。

使用场景

线程操作可以应用于很多场景,比如:
多线程下载文件:可以使用多个线程同时下载文件,提高下载速度。
多线程处理数据:可以使用多个线程同时处理数据,提高处理效率。
多线程编程游戏:可以使用多个线程处理游戏逻辑和渲染,提高游戏性能。
多线程爬虫:可以使用多个线程同时爬取网页,提高爬虫效率。
当然,使用线程操作时需要注意线程安全性问题,避免出现竞态条件等问题。同时也需要注意线程间通信的问题,确保线程间可以正确地传递信息。

你可能感兴趣的:(c++,开发语言)