C/C++基于线程的并发编程(二):线程安全和互斥锁
2021/5/23 22:28:33
本文主要是介绍C/C++基于线程的并发编程(二):线程安全和互斥锁,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
导航
- 线程安全
- 线程不安全例子
- 线程锁
- 互斥锁
- C++线程安全实现
- C语言线程安全实现
线程安全
所谓线程安全不是指线程的安全,而是指内存的安全。线程是由进程所承载,所有线程均可访问进程的上下文,意味着所有线程均可访问在进程中的内存空间,这也是线程之间造成问题的潜在原因。当多个线程读取同一片内存空间(变量、对象等)时,不会引起线程安全问题。但是当多个线程对同一片内存空间进行写操作时,就需要考虑内存安全问题。
线程不安全例子
#include <iostream> #include <thread> using namespace std; int counter = 0; void func() { for (int i = 0; i < 10000; ++i) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); // 休眠1ms ++counter; // 写入操作:counter自加 } } int main() { std::thread t1 = std::thread(func); std::thread t2 = std::thread(func); t1.join(); t2.join(); cout << "counter: " << counter << endl; return 0; }
上述代码,预期结果是counter输出20000,因为两个线程均会进入循环,counter各自自加10000次。实际输出效果如下:
counter: 19989
counter: 19992
两次输出结果均不相同,且均不等于预期的20000。这就线程不安全导致的BUG。
线程锁
为了解决上述线程安全问题,就需要线程锁,C和C++最常用的锁包括互斥锁、条件锁、自旋锁和读写锁等。其中最基本的是互斥锁,其他的锁都是基于互斥锁实现。所以锁的功能越强大,性能就越低。
互斥锁
互斥锁(mutex),也成为互斥量,就是保证多线程共享同一个互斥量,然后让线程之间。当一个线程对共享数据操作时,利用互斥锁进行上锁,其他线程在尝试再次上锁时,发现已上锁就会睡眠等待。等到互斥锁解开,才能再次上锁进而继续操作,从而保护共享数据的安全。下面利用互斥锁,解决上述BUG。
C++线程安全实现
#include <iostream> #include <thread> #include <mutex> int counter = 0; std::mutex mutex; void func() { for (int i = 0; i < 10000; ++i) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); mutex.lock(); ++counter; mutex.unlock(); } } int main() { std::thread t1 = std::thread(func); std::thread t2 = std::thread(func); t1.join(); t2.join(); std::cout << "counter: " << counter << std::endl; return 0; }
输出结果如下:
counter: 20000
counter: 20000
两次运行输出均为20000,与预期结果相同,证明加入互斥锁后解决线程安全问题。
C语言线程安全实现
#include <stdio.h> #include <pthread.h> #include <unistd.h> int counter = 0; pthread_mutex_t mutex; void *func(void *val) { for (int i = 0; i < 10000; ++i) { usleep(1 * 1000); pthread_mutex_lock(&mutex); ++counter; pthread_mutex_unlock(&mutex); } } int main() { pthread_mutex_init(&mutex, NULL); pthread_t t1; pthread_t t2; pthread_create(&t1, NULL, func, NULL); pthread_create(&t2, NULL, func, NULL); pthread_join(t1, NULL); pthread_join(t2, NULL); pthread_mutex_destroy(&mutex); printf("counter: %d\n", counter); return 0; }
输出如下:
counter: 20000
输出也是预期的20000。
这篇关于C/C++基于线程的并发编程(二):线程安全和互斥锁的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-06-29易优CMS安装常见问题汇总-icode9专业技术文章分享
- 2024-06-28易优新手必读安装教程-icode9专业技术文章分享
- 2024-06-28忘记eyoucms后台密码怎么办?-icode9专业技术文章分享
- 2024-06-26终极指南:Scrum中如何设置需求优先级
- 2024-06-26AI大模型企业应用实战(25)-为Langchain Agent添加记忆功能
- 2024-06-26小白家庭 nas 搭建方案-icode9专业技术文章分享
- 2024-06-23AI大模型企业应用实战(14)-langchain的Embedding
- 2024-06-23AI大模型企业应用实战(15)-langchain核心组件
- 2024-06-23AI大模型企业应用实战(16)-langchain核心组件
- 2024-06-23AI 大模型企业应用实战(06)-初识LangChain