C++11之线程库(Thread、Mutex、atomic、lock_guard、同步)

简介: C++11之线程库(Thread、Mutex、atomic、lock_guard、同步)

线程库C++11

在C++ 11引入了对多线程的支持。包括线程、互斥锁、原子操作、自动加减锁和同步。下面就分别介绍一下对应的用法。


线程Thread

线程:系统分配cup时间和调度的基本单位

头文件

#include<thread>

常用的成员函数

函数名 作用
get_id() 获取当前线程ID
join() 等待
detach() 分离


创建线程的方式

thread t1(函数地址);//无参

thread t2(函数地址,参数1,参数2,…);//有参

A a;

thread t3(&A::output,&a);成员函数,


全局函数实例:

#include <thread>
#include <string>
#include <iostream>
using namespace std;
void test1(string name)//子线程 有参
{
    for (int i = 0; i < 100; ++i)
    {
        cout << name <<  " test1:" << i << endl;
    }
}
void test2()//子线程
{
    for (int i = 0; i < 100; ++i)
    {
        cout << "test2:" << i << endl;
    }
}
int main()
{
    thread t1(test1, "线程1");//创建线程 并启动线程
    thread t2(test2);
    t1.join();//等待线程执行结束,不写会造成程序崩溃
    t2.join();
    return 0;
}


成员函数实例:

class A
{
public:
    void output(string name)
    {
        cout << "线程执行 " << name << endl;
    }
};
int main()
{
    A a;
    //格式:thread t1(函数地址 对象地址 参数1 参数2...)
    thread t1(&A::output, &a, "线程一");//成员函数做线程
    t1.join();
    return 0;
}


多线程的冲突问题

a. 出现了更高等级的指令

b. 该线程的时间片到了

互斥体Mutex

头文件

#include<mutex>

常用的成员函数

函数名 作用
lock() 加锁
unlock() 解锁


实例

#include <thread>
#include <string>
#include <iostream>
#include <mutex>
using namespace std;
int g_a = 0;
mutex g_m;//创建锁
void test3()
{
    for (int i = 0; i < 1000000; ++i)
    {
        //保证数据的完整性
        g_m.lock();//加锁
        g_a += 1;
        g_m.unlock();//解锁
    }
}
int main()
{
    thread t1(test3);
    thread t2(test3);
    thread t3(test3);
    t1.join();
    t2.join();
    t3.join();
    cout << g_a << endl;
    return 0;
}


原子操作Atomic

头文件

#include<atomic>

实例

#include <thread>
#include <iostream>
#include <atomic>
using namespace std;
atomic_int a;//将这个变量设置为int原子级别
void test3()
{
    for (int i = 0; i < 1000000; ++i)
    {
        ++a;//在执行过程中,等同于锁
    }
}
int main()
{
    thread t1(test3);
    thread t2(test3);
    thread t3(test3);
    t1.join();
    t2.join();
    t3.join();
    cout << a << endl;
    return 0;
}


自动加解锁lock_guard

在创建时调用构造函数自动加锁,出了作用域就调用析构函数解锁。

实例

#include <thread>
#include <string>
#include <iostream>
#include <mutex>
#include <atomic>
using namespace std;
int a = 0;
mutex g_m;//创建锁
void test3()
{
    for (int i = 0; i < 1000000; ++i)
    {
        lock_guard<mutex> la(g_m);//自动加锁 自动释放
        ++a;
        cout << a << endl;
    }
}
int main()
{
    thread t1(test3);
    thread t2(test3);
    thread t3(test3);
    t1.join();
    t2.join();
    t3.join();
    cout << a << endl;
    return 0;
}


同步

同步方式

  1. 信号量
  2. 事件
  3. 消息
  4. C++11中的条件变量

实例

#include <thread>
#include <string>
#include <iostream>
#include <mutex>
#include <atomic>
#include <string>
#include <condition_variable>
using namespace std;
string  buffer;
mutex m; 
condition_variable cv; //状态变量
//为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起;
void workThread()
{
    //unique_lock比lock_guard灵活很多,效率上差一点,内存占用多一点。
    unique_lock<mutex> lk(m);
    cv.wait(lk);//等待信号
    cout << "收到数据:" << buffer << endl;
}
int main()
{
    thread t1(workThread);
    string name;
    cin >> name;
    buffer = name;
    cv.notify_all();//发出通知
    t1.join();
    cout << "数据处理完成" << endl;
    return 0;
}
目录
相关文章
|
21天前
|
数据采集 Java API
Jsoup库能处理多线程下载吗?
Jsoup库能处理多线程下载吗?
|
28天前
|
Java C# Python
线程等待(Thread Sleep)
线程等待是多线程编程中的一种同步机制,通过暂停当前线程的执行,让出CPU时间给其他线程。常用于需要程序暂停或等待其他线程完成操作的场景。不同语言中实现方式各异,如Java的`Thread.sleep(1000)`、C#的`Thread.Sleep(1000)`和Python的`time.sleep(1)`。使用时需注意避免死锁,并考虑其对程序响应性的影响。
|
1月前
|
Java 调度
Java 线程同步的四种方式,最全详解,建议收藏!
本文详细解析了Java线程同步的四种方式:synchronized关键字、ReentrantLock、原子变量和ThreadLocal,通过实例代码和对比分析,帮助你深入理解线程同步机制。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
Java 线程同步的四种方式,最全详解,建议收藏!
|
2月前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
32 3
|
2月前
|
Java
在Java多线程编程中,实现Runnable接口通常优于继承Thread类
【10月更文挑战第20天】在Java多线程编程中,实现Runnable接口通常优于继承Thread类。原因包括:1) Java只支持单继承,实现接口不受此限制;2) Runnable接口便于代码复用和线程池管理;3) 分离任务与线程,提高灵活性。因此,实现Runnable接口是更佳选择。
56 2
|
2月前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
41 2
|
2月前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
47 1
|
2月前
|
安全 Java 开发者
Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用
本文深入解析了Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用。通过示例代码展示了如何正确使用这些方法,并分享了最佳实践,帮助开发者避免常见陷阱,提高多线程程序的稳定性和效率。
53 1
|
2月前
|
安全 调度 C#
STA模型、同步上下文和多线程、异步调度
【10月更文挑战第19天】本文介绍了 STA 模型、同步上下文和多线程、异步调度的概念及其优缺点。STA 模型适用于单线程环境,确保资源访问的顺序性;同步上下文和多线程提高了程序的并发性和响应性,但增加了复杂性;异步调度提升了程序的响应性和资源利用率,但也带来了编程复杂性和错误处理的挑战。选择合适的模型需根据具体应用场景和需求进行权衡。
|
2月前
多线程通信和同步的方式有哪些?
【10月更文挑战第6天】
127 0