C++线程浅谈

简介: C++线程浅谈

本篇文章我们来介绍一下C++ 多进程 多线程的技术

1.为什要学习多线程 多进程

  1. 提高程序的性能:进程和线程可以使程序并发执行,从而充分利用计算机的多核处理器和资源,提高程序的执行效率和吞吐量。
  2. 实现复杂任务:通过将任务划分为多个子任务,每个子任务由一个线程或进程处理,可以更好地组织和管理代码。这样可以降低代码的复杂性,并且易于调试和维护。
  3. 支持并发编程:进程和线程是实现并发编程的基础。并发编程可以让多个任务在同一时间段内交替执行,提供更好的用户体验,例如同时响应用户输入、处理网络请求等。
  4. 充分利用系统资源:操作系统以及底层硬件通常采用多进程或多线程的方式来管理资源。了解进程和线程的工作原理可以帮助我们更好地使用系统资源,避免资源竞争和浪费。
  5. 解决共享数据问题在多线程编程中,需要考虑到共享数据访问时可能出现的竞争条件。了解进程和线程之间的通信与同步机制可以帮助我们设计安全可靠的并发程序

例如游戏服务器

多线程能够很好的处理多个玩家的问题 可以有效地避免阻塞

处理器处理只需要几毫秒的时间 就算玩家的请求比服务器多 也可以快速的提供服务

2.如何实现多线程

进程:执行起来的可运行程序

主线程 :每一个进程产生的一个线程

多线程实现案例:

#include <iostream>
#include <thread>
// 线程函数,计算从start到end的平方和
void squareSum(int start, int end, long long& result) {
    result = 0;
    for (int i = start; i <= end; ++i) {
        result += i * i;
    }
}
int main() {
    long long sum1 = 0, sum2 = 0;
    // 创建两个线程分别计算1-5和6-10的平方和
    std::thread thread1(squareSum, 1, 5, std::ref(sum1));
    std::thread thread2(squareSum, 6, 10, std::ref(sum2));
    // 等待两个线程执行完毕
    thread1.join();
    thread2.join();
    // 输出结果
    std::cout << "Sum of squares from 1 to 5: " << sum1 << std::endl;
    std::cout << "Sum of squares from 6 to 10: " << sum2 << std::endl;
    std::cout << "Total sum: " << sum1 + sum2 << std::endl;
    return 0;
}

在这个案例中,我们使用std::thread库创建了两个线程,分别计算从1到5和从6到10的平方和。每个线程将自己的结果存储在一个引用参数中。然后,通过调用join()函数等待两个线程执行完毕,并将最终结果输出到控制台。

需要注意的是,在多线程编程中,我们需要考虑到共享数据访问时可能出现的竞争条件。为了避免潜在的问题,可以使用互斥锁(std::mutex)或其他同步机制来确保线程安全。

3.互斥锁 线程池等知识

互斥锁(Mutex)是一种用于多线程编程的同步机制,它可以防止多个线程同时访问共享资源导致的竞争条件。

 

线程池(Thread Pool)是一种用于管理和复用线程的技术,它可以提供更高效的线程管理和任务调度机制。

在多线程编程中,创建和销毁线程是比较耗费资源的操作。而且,频繁地创建和销毁线程可能导致系统性能下降。线程池的思想就是将一组预先创建好的线程放入一个池中,并维护这些线程的生命周期。当有任务需要执行时,从线程池中获取一个空闲的线程来执行任务,完成后再放回线程池以便复用。

互斥锁代码实例:

#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx; // 定义一个互斥锁
int sharedData = 0;
void updateData() {
    std::lock_guard<std::mutex> lock(mtx); // 使用lock_guard自动管理锁的加解锁过程
    ++sharedData;
}
int main() {
    std::thread thread1(updateData);
    std::thread thread2(updateData);
    thread1.join();
    thread2.join();
    std::cout << "Shared data: " << sharedData << std::endl;
    return 0;
}

线程池代码实例:

#include <iostream>
#include <thread>
#include <vector>
#include <queue>
#include <functional>
#include <mutex>
#include <condition_variable>
class ThreadPool {
public:
    ThreadPool(size_t numThreads) : stop(false) {
        for (size_t i = 0; i < numThreads; ++i) {
            threads.emplace_back([this] {
                while (true) {
                    std::function<void()> task;
                    
                    // 获取任务
                    {
                        std::unique_lock<std::mutex> lock(queueMutex);
                        condition.wait(lock, [this]{ return stop || !tasks.empty(); });
                        
                        if (stop && tasks.empty()) {
                            return;
                        }
                        
                        task = std::move(tasks.front());
                        tasks.pop();
                    }
                    
                    // 执行任务
                    task();
                }
            });
        }
    }
    template<typename F, typename... Args>
    void enqueue(F&& f, Args&&... args) {
        // 将任务包装成函数并添加到队列中
        {
            std::unique_lock<std::mutex> lock(queueMutex);
            tasks.emplace([f, args...] { f(args...); });
        }
        
        condition.notify_one(); // 唤醒一个线程来执行任务
    }
    ~ThreadPool() {
        {
            std::unique_lock<std::mutex> lock(queueMutex);
            stop = true;
        }
        condition.notify_all();
        for (std::thread& thread : threads) {
            thread.join();
        }
    }
private:
    std::vector<std::thread> threads;
    std::queue<std::function<void()>> tasks;
    std::mutex queueMutex;
    std::condition_variable condition;
    bool stop;
};
// 示例任务函数
void taskFunction(int id) {
    std::cout << "Task " << id << " executed by thread " << std::this_thread::get_id() << std::endl;
}
int main() {
    ThreadPool pool(4); // 创建一个大小为4的线程池
    // 添加10个任务到线程池中
    for (int i = 0; i < 10; ++i) {
        pool.enqueue(taskFunction, i);
    }
    return 0;
}

在上述示例中,我们首先定义了一个ThreadPool类,其中包含了一个存储线程对象的std::vector容器和一个任务队列(使用std::queue),以及相应的互斥锁和条件变量用于线程同步。

在构造函数中,我们根据指定的线程数量创建了对应数量的线程,并通过Lambda表达式定义了每个线程要执行的工作。每个线程循环地从任务队列中获取任务并执行,直到停止标志被设置为true。

enqueue()函数中,我们将需要执行的任务封装成一个函数,并添加到任务队列中。之后通过调用condition.notify_one()唤醒一个空闲的线程来执行该任务。

最后,在析构函数中,我们设置停止标志为true,并通过调用condition.notify_all()来通知所有线程停止运行。然后等待每个线程结束运行。

 

总结:

1.常用的线程函数  std::thread  std::this_thread::sleep_for  std::mutex.....

2.掌握多线程编程知识 能够帮助我们实现大型项目的制作 大并发和百万级服务器  掌握线程池  互斥锁 原子锁等知识 能够完美的实现资源节约的功能

好了 本篇文章就到这里 在这里我想向大家推荐一个课程:

https://xxetb.xetslk.com/s/2PjJ3T

 

相关文章
|
2月前
|
缓存 安全 C++
C++无锁队列:解锁多线程编程新境界
【10月更文挑战第27天】
78 7
|
2月前
|
消息中间件 存储 安全
|
3月前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
62 1
|
3月前
|
存储 并行计算 安全
C++多线程应用
【10月更文挑战第29天】C++ 中的多线程应用广泛,常见场景包括并行计算、网络编程中的并发服务器和图形用户界面(GUI)应用。通过多线程可以显著提升计算速度和响应能力。示例代码展示了如何使用 `pthread` 库创建和管理线程。注意事项包括数据同步与互斥、线程间通信和线程安全的类设计,以确保程序的正确性和稳定性。
|
3月前
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
97 6
|
3月前
|
缓存 负载均衡 Java
c++写高性能的任务流线程池(万字详解!)
本文介绍了一种高性能的任务流线程池设计,涵盖多种优化机制。首先介绍了Work Steal机制,通过任务偷窃提高资源利用率。接着讨论了优先级任务,使不同优先级的任务得到合理调度。然后提出了缓存机制,通过环形缓存队列提升程序负载能力。Local Thread机制则通过预先创建线程减少创建和销毁线程的开销。Lock Free机制进一步减少了锁的竞争。容量动态调整机制根据任务负载动态调整线程数量。批量处理机制提高了任务处理效率。此外,还介绍了负载均衡、避免等待、预测优化、减少复制等策略。最后,任务组的设计便于管理和复用多任务。整体设计旨在提升线程池的性能和稳定性。
89 5
|
3月前
|
C++
C++ 多线程之线程管理函数
这篇文章介绍了C++中多线程编程的几个关键函数,包括获取线程ID的`get_id()`,延时函数`sleep_for()`,线程让步函数`yield()`,以及阻塞线程直到指定时间的`sleep_until()`。
48 0
|
3月前
|
资源调度 Linux 调度
Linux C/C++之线程基础
这篇文章详细介绍了Linux下C/C++线程的基本概念、创建和管理线程的方法,以及线程同步的各种机制,并通过实例代码展示了线程同步技术的应用。
40 0
Linux C/C++之线程基础
|
5月前
|
Java 调度
基于C++11的线程池
基于C++11的线程池
|
4月前
|
JavaScript 安全 前端开发
ArkTS线程中通过napi创建的C++线程
需要注意的是,N-API和ArkTS的具体使用会随Node.js的版本不断更新和变化,所以在实际编写代码前,查看最新的官方文档是很重要的,以了解最新的最佳实践和使用模式。此外,C++线程的使用在Node.js插件中应当慎重,过多地使用它们可能会造成资源争用,并可能降低应用程序的性能。
96 0