C++多线程编程和同步机制:详解和实例演示

小万哥
• 阅读 208

C++中的多线程编程和同步机制使得程序员可以利用计算机的多核心来提高程序的运行效率和性能。本文将介绍多线程编程和同步机制的基本概念和使用方法。

多线程编程基础

在C++中,使用<thread>库来创建和管理线程。线程可以通过函数、成员函数或者Lambda表达式来实现。以下是一个使用Lambda表达式来创建线程的例子:

#include <thread>
#include <iostream>

int main() {
    std::thread t([](){
        std::cout << "Hello from thread " << std::this_thread::get_id() << std::endl;
    });
    t.join();
    return 0;
}

data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

上述代码创建了一个线程并输出了该线程的ID。在创建线程时,需要将线程函数作为参数传递给std::thread。在上述例子中,我们使用了Lambda表达式来定义线程函数,该表达式会输出一行文本。

同步机制

多线程编程中最常见的问题是数据竞争和死锁。为了避免这些问题,我们需要使用同步机制来控制线程的访问。

互斥量

互斥量是C++中最常用的同步机制之一。互斥量可以保证同一时间只有一个线程可以访问共享资源。以下是一个使用互斥量来保护共享资源的例子:

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

std::mutex mtx;

void thread_func() {
    mtx.lock();
    std::cout << "Hello from thread " << std::this_thread::get_id() << std::endl;
    mtx.unlock();
}

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

data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

上述代码创建了两个线程,并使用互斥量来保护共享资源。在线程函数中,我们先调用mtx.lock()函数来锁定互斥量,然后访问共享资源,最后再调用mtx.unlock()函数来释放互斥量。在上述例子中,我们使用了两个线程来访问共享资源,但是只有一个线程可以访问该资源。这是因为在一个线程访问共享资源时,该资源会被锁定,其他线程无法访问该资源,直到该线程释放互斥量为止。

条件变量

条件变量是C++中另一个常用的同步机制。条件变量可以让线程在某些条件满足时才继续执行,否则就等待。以下是一个使用条件变量来同步线程的例子:

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

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

void consumer() {
    std::unique_lock<std::mutex> lock(mtx);
    cv.wait(lock, [](){ return ready; });
    std::cout << "Hello from consumer thread " << std::this_thread::get_id() << std::endl;
}

void producer() {
    std::this_thread::sleep_for(std::chrono::seconds(1));
    ready = true;
    cv.notify_one();
}

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

data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

上述代码创建了两个线程,一个生产者线程和一个消费者线程。生产者线程在1秒后将ready变量设置为true,然后通知消费者线程继续执行。消费者线程等待条件变量cv,直到ready变量的值为true为止。在该例子中,我们使用了条件变量来同步生产者和消费者线程。

结论

多线程编程和同步机制是C++中非常重要的主题。本文介绍了多线程编程的基本概念和使用方法,以及互斥量和条件变量等常用的同步机制。希望这篇文章对你有所帮助。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
2年前
PPDB:今晚老齐直播
【今晚老齐直播】今晚(本周三晚)20:0021:00小白开始“用”飞桨(https://www.oschina.net/action/visit/ad?id1185)由PPDE(飞桨(https://www.oschina.net/action/visit/ad?id1185)开发者专家计划)成员老齐,为深度学习小白指点迷津。
Peter20 Peter20
3年前
mysql中like用法
like的通配符有两种%(百分号):代表零个、一个或者多个字符。\(下划线):代表一个数字或者字符。1\.name以"李"开头wherenamelike'李%'2\.name中包含"云",“云”可以在任何位置wherenamelike'%云%'3\.第二个和第三个字符是0的值wheresalarylike'\00%'4\
Wesley13 Wesley13
2年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
2年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Wesley13 Wesley13
2年前
MBR笔记
<bochs:100000000000e\WGUI\Simclientsize(0,0)!stretchedsize(640,480)!<bochs:2b0x7c00<bochs:3c00000003740i\BIOS\$Revision:1.166$$Date:2006/08/1117
Stella981 Stella981
2年前
Jenkins 插件开发之旅:两天内从 idea 到发布(上篇)
本文首发于:Jenkins中文社区(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fjenkinszh.cn)!huashan(https://oscimg.oschina.net/oscnet/f499d5b4f76f20cf0bce2a00af236d10265.jpg)
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_