详解C++11中的线程库

详解C++11中的线程库

C++11引入了线程库,这使得C++程序员可以轻松地编写多线程应用程序。线程库提供了一个标准化的方式来执行并发任务和同步不同线程之间的访问。

基础概念

线程的创建和执行

线程是计算机系统执行的最小的单位。在C++11中,线程的创建和执行非常简单,并且通过std::thread类实现。

我们可以使用std::thread对象的构造函数来创建一个新的线程,并传递一个可以执行的函数作为参数。如果这个函数需要参数,可以将参数通过std::ref传递给std::thread构造函数。

以下是一个简单的例子:

#include <iostream>
#include <thread>

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

int main()
{
    std::thread t(HelloFunction);

    t.join();

    return 0;
}

在这个例子中,我们创建了一个名为t的线程,并通过HelloFunction函数作为参数来启动该线程。该线程执行HelloFunction函数并输出一条消息。在main函数最后,我们对线程进行了等待操作,确保线程执行完成后程序才继续执行。

线程的同步

在多线程的环境下,线程之间需要进行同步来保证共享资源的正确性,即只有一个线程能够访问共享资源。C++11提供了多种同步机制来实现线程同步。

  • Mutex:互斥量(Mutual Exclusion)控制对共享资源的访问。在某个线程访问共享资源时,可以加锁( lock() ),当操作结束后解锁( unlock() ),使得其它的线程可以访问该共享资源。

下面这个例子演示了如何使用std::mutex来保护共享变量的访问:

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

std::mutex mtx; //锁对象

void PrintNum(int i)
{
    mtx.lock();
    std::cout << "Thread " << std::this_thread::get_id() << " executed i= " << i << std::endl;
    mtx.unlock();
}

int main()
{
    std::thread t[10];

    for (int i = 0; i < 10; i++)
    {
        t[i] = std::thread(PrintNum, i);
    }

    for (int i = 0; i < 10; i++)
    {
        t[i].join();
    }

    return 0;
}

在这个例子中,我们使用std::mutex对象mtx来保护共享的PrintNum函数。在每个线程中访问共享变量i之前使用mtx.lock()进行加锁,在对i的访问结束后使用mtx.unlock()解锁,在多线程环境中(多线程可能同时访问i),互斥锁保证了i的访问操作是线程安全的。

  • Condition Variable:条件变量在等待某种条件满足时,可以让线程进入等待状态,并在条件得到满足时唤醒线程。

下面这个例子演示了如何使用std::condition_variable:

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

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

void WorkerThread()
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
    {
        std::lock_guard<std::mutex> lock(mtx);
        dataReady = true;
        std::cout << "Worker thread signals data ready!" << std::endl;
    }
    cv.notify_one();
}

int main()
{
    std::thread workerThread(WorkerThread);

    {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, []{ return dataReady; });
    }

    std::cout << "Main thread got notified!" << std::endl;

    workerThread.join();

    return 0;
}

在这个例子中,我们首先创建了一个子线程,并通过std::condition_variable对象cv来等待数据的到来。在子线程中,当数据准备好的时候设置bool变量dataReady为true并调用cv.notify_one()唤醒().在主线程中,使用std::unique_lock lock(mtx)加锁,并使用cv.wait(lock, []{ return dataReady; });等待数据的到来。在主线程中等待过程中,因为没有数据,所以线程会陷入等待状态并在条件得到满足后自动被唤醒。

总结

C++11中的线程库提供了一种简单的方式来编写多线程应用程序。本文介绍了线程的创建和执行,同时还讨论了线程同步的机制,如mutual exclusion和条件变量。这些机制为我们提供了一种可重用的方式来保护共享资源并确保线程安全。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解C++11中的线程库 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • vscode调用c项目后怎么引用dll?

    在VSCode中调用C语言项目,如果需要使用动态链接库(DLL)的话,一般需要进行以下步骤: 创建动态链接库 先编写动态链接库的代码并生成DLL文件。例如,编写一个示例代码,将其保存为 “hello.c”,编译并生成DLL文件 “hello.dll”。示例代码如下: #include <stdio.h> #include <stdlib.h…

    C 2023年5月23日
    00
  • C语言 指针和数组

    让我们来详细讲解一下C语言中指针和数组的使用攻略。 指针和数组 指针 指针是一种特殊的变量,其存储的是另一个变量的地址。在C语言中,可以通过指针来访问和修改该变量的值,也可以用指针来实现动态内存分配。指针变量的声明格式如下: type *name; 其中,type是指针变量所指向变量的类型,name是指针变量的名称。 指针操作符 按照指针操作的不同,可以将指…

    C 2023年5月9日
    00
  • 如何用c++表驱动替换if/else和switch/case语句

    当在编写C++代码时,经常需要使用if/else和switch/case语句对不同的条件进行处理。这些语句可以让程序员更加方便地编写逻辑代码。但是,当逻辑变得越来越复杂时,这些语句将变得越来越难以维护。因此,使用表驱动来代替if/else和switch/case语句将会变得更加方便和容易维护。 表驱动的思想是将输入值作为数组的下标,将对应的输出值存储在数组中…

    C 2023年5月23日
    00
  • python中的Json模块dumps、dump、loads、load函数用法详解

    下面是关于 Python 中的 Json 模块 dumps、dump、loads、load 函数的使用详解: Json 简介 Json是一种基于文本的轻量级数据交换格式,常用于前后端数据交互、配置文件等场合。在 Python 中,可以使用 Json 模块来对 Json 数据进行解析和生成。 Json 模块函数说明 dumps 函数 dumps 函数将一个 P…

    C 2023年5月23日
    00
  • 基于javascript实现按圆形排列DIV元素(二)

    基于JavaScript实现按圆形排列DIV元素的完整攻略如下: 步骤1:构建HTML结构 首先,我们需要构建一个HTML页面,并在其中添加一个父级div元素和一些子级的div元素。父级div元素用于容纳所有子级div元素,并设置其宽度和高度为固定值,例如600px。子级div元素用于显示实际内容,我们只需要设置它们的宽度和高度即可。 <div id=…

    C 2023年5月22日
    00
  • C语言中如何实现桶排序

    C语言中实现桶排序,其主要思想是将待排序的序列分解成若干个区间,对于每个区间分别使用一个桶来存放该区间内的元素,然后对每个桶中的元素进行排序,最后按照桶的顺序将所有元素连接起来,就得到了排好序的序列。 具体的实现步骤如下: 1.确定桶的数量和区间范围。根据序列中的元素取值范围,确定桶的数量并计算区间大小。 2.将元素分配到对应的桶中。遍历待排序的序列,将每个…

    C 2023年5月22日
    00
  • Win11更新失败并提示0xc1900101怎么办?Win11错误提示0xc1900101解决方法

    Win11更新失败并提示0xc1900101是一个常见的问题,它可能发生在更新到Windows 11时。这个错误代码可能是由于硬件与软件不兼容、设备驱动程序不正确、磁盘空间不足以及许多其他原因引起的。下面我们来详细讲解Win11更新失败并提示0xc1900101该如何解决。 检查计算机硬件与设备 在更新之前,必须检查计算机的硬件是否与Windows 11兼容…

    C 2023年5月23日
    00
  • 十个C++恶搞朋友的代码合集

    这篇攻略会对“十个C++恶搞朋友的代码合集”进行详细讲解,介绍每个代码的用途和实现方式。以下是每个代码及其说明: 1. 静态断言 这个文件定义了一个静态断言的宏 static_assert(),如果编译器在编译过程中发现了 false 的表达式,那么编译将失败。以下是一个示例: static_assert(sizeof(int) == 8, "in…

    C 2023年5月24日
    00
合作推广
合作推广
分享本页
返回顶部