在Linux环境下,C++多线程同步是一个重要的主题,多线程编程可以提高程序的执行效率,但是也带来了一些问题,如数据竞争和死锁等,为了解决这些问题,我们需要使用一些同步机制来保证线程之间的安全操作,本文将介绍几种常用的Linux C++多线程同步方式。
1、互斥量(Mutex)
互斥量是一种用于保护共享资源的同步原语,当一个线程拥有互斥量的所有权时,其他线程无法访问被保护的资源,当线程完成对共享资源的访问后,它会释放互斥量,允许其他线程访问。
在Linux下,我们可以使用pthread_mutex_t
类型的变量来表示互斥量,以下是一个简单的互斥量使用示例:
#include <pthread.h> #include <iostream> pthread_mutex_t mutex; void* thread_function(void* arg) { pthread_mutex_lock(&mutex); // 加锁 std::cout << "线程 " << pthread_self() << " 正在运行" << std::endl; pthread_mutex_unlock(&mutex); // 解锁 return nullptr; } int main() { pthread_t threads[5]; for (int i = 0; i < 5; ++i) { pthread_create(&threads[i], nullptr, thread_function, nullptr); } for (int i = 0; i < 5; ++i) { pthread_join(threads[i], nullptr); } return 0; }
2、条件变量(Condition Variable)
条件变量是一种同步原语,用于阻塞一个或多个线程,直到它们满足某个条件,条件变量通常与互斥量一起使用,以确保在检查条件和等待条件成立之间,共享资源不会被其他线程修改。
在Linux下,我们可以使用pthread_cond_t
类型的变量来表示条件变量,以下是一个简单的条件变量使用示例:
#include <pthread.h> #include <iostream> #include <unistd.h> pthread_mutex_t mutex; pthread_cond_t cond; bool ready = false; void* thread_function(void* arg) { pthread_mutex_lock(&mutex); // 加锁 while (!ready) { // 等待条件成立 pthread_cond_wait(&cond, &mutex); // 等待条件成立 } std::cout << "线程 " << pthread_self() << " 开始运行" << std::endl; pthread_mutex_unlock(&mutex); // 解锁 return nullptr; } void set_ready() { pthread_mutex_lock(&mutex); // 加锁 ready = true; pthread_cond_signal(&cond); // 通知等待的线程 pthread_mutex_unlock(&mutex); // 解锁 } int main() { pthread_t threads[5]; for (int i = 0; i < 5; ++i) { pthread_create(&threads[i], nullptr, thread_function, nullptr); } sleep(1); // 主线程等待1秒,让子线程准备好信号量和条件变量 set_ready(); // 设置条件成立,唤醒等待的线程 for (int i = 0; i < 5; ++i) { pthread_join(threads[i], nullptr); } return 0; }
3、读写锁(ReadWrite Lock)
读写锁是一种适用于读多写少场景的同步原语,它允许多个线程同时读取共享资源,但是在写入共享资源时,只允许一个线程进行操作,读写锁分为两种类型:读锁和写锁,当一个线程拥有读锁时,其他线程可以继续获取读锁;当一个线程拥有写锁时,其他线程不能获取读锁和写锁。
在Linux下,我们可以使用pthread_rwlock_t
类型的变量来表示读写锁,以下是一个简单的读写锁使用示例:
#include <pthread.h> #include <iostream> #include <unistd.h> #include <vector> #include <algorithm> #include <numeric> #include <random> #include <chrono> #include <ctime> #include <cstdlib> #include <iterator> #include <typeinfo> #include <typeindex> #include <string> #include <sstream> #include <iomanip> #include <cmath> #include <limits> #include <exception> #include <stdexcept> #include <new> // for std::bad_alloc exception type and std::nothrow constant for new operator in C++11 and later versions of the standard library. It is not necessary to include this header file if you are using an older version of the standard library that does not support these features. However, it is a good practice to include it to avoid potential compilation errors when upgrading to a newer version of the standard library in the future.
原创文章,作者:K-seo,如若转载,请注明出处:https://www.kdun.cn/ask/512624.html