C++实现线程同步的四种方式总结
在多线程程序中,线程同步是一个非常重要的问题。为了保证多个线程的正确性和稳定性,我们需要采用线程同步措施,这样才能确保多个线程同时处理共享资源时不会出现数据读写冲突等问题。C++中实现线程同步主要有四种方式:互斥锁、条件变量、信号量和读写锁。
一、互斥锁(Mutex)
1. 互斥锁概念
互斥锁是最基本的线程同步机制。一段代码被互斥锁保护时,同一时间只有一个线程能够执行它。如果有其他线程在等待这个锁,那么它们会被阻塞,直到该锁被释放为止。pthread_mutex_t为互斥锁类型,可以通过pthread_mutex_init、pthread_mutex_lock、pthread_mutex_trylock、pthread_mutex_unlock等函数使用此类型进行相关的操作。
2. 示例
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t mutex;
void* thread_func(void* data)
{
// 加锁
pthread_mutex_lock(&mutex);
// do something
// 释放锁
pthread_mutex_unlock(&mutex);
return NULL;
}
int main(int argc, char** argv)
{
pthread_t thread;
// 初始化互斥锁
pthread_mutex_init(&mutex, NULL);
// 创建线程
pthread_create(&thread, NULL, thread_func, NULL);
// 加锁
pthread_mutex_lock(&mutex);
// do something
// 释放锁
pthread_mutex_unlock(&mutex);
// 等待线程结束
pthread_join(thread, NULL);
// 销毁互斥锁
pthread_mutex_destroy(&mutex);
return 0;
}
在示例中,我们使用pthread_mutex_t定义一个互斥锁类型mutex,通过pthread_mutex_lock函数获取锁,通过pthread_mutex_unlock函数释放锁。在主线程中,我们先获取锁,然后执行一些操作,最后释放锁。在子线程中,我们需要先获取锁,才能执行操作。
二、条件变量(Condition Variable)
1. 条件变量概念
条件变量是一种同步机制,用于解决一个线程必须等待另外一个线程完成某项操作后才能继续执行的情况。pthread_cond_t为条件变量类型,可以通过pthread_cond_init、pthread_cond_wait、pthread_cond_signal、pthread_cond_broadcast等函数使用此类型进行相关的操作。
2. 示例
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t mutex;
pthread_cond_t cond;
void* thread_func(void* data)
{
// 加锁
pthread_mutex_lock(&mutex);
// 等待条件变量
pthread_cond_wait(&cond, &mutex);
// do something
// 释放锁
pthread_mutex_unlock(&mutex);
return NULL;
}
int main(int argc, char** argv)
{
pthread_t thread;
// 初始化互斥锁和条件变量
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
// 创建线程
pthread_create(&thread, NULL, thread_func, NULL);
// 加锁
pthread_mutex_lock(&mutex);
// do something
// 通知条件变量
pthread_cond_signal(&cond);
// 释放锁
pthread_mutex_unlock(&mutex);
// 等待线程结束
pthread_join(thread, NULL);
// 销毁互斥锁和条件变量
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}
在示例中,我们定义一个条件变量cond,通过pthread_cond_wait函数等待条件变量的信号,通过pthread_cond_signal函数发送条件变量信号。
三、信号量(Semaphore)
1. 信号量概念
信号量是一种同步机制,主要用于控制多个线程之间对共享资源的访问。通常用于限制同时访问某些资源的线程数量,控制并发线程的数量。sem_t为信号量类型,可以通过sem_init、sem_wait、sem_post、sem_destroy等函数使用此类型进行相关的操作。
2. 示例
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
sem_t sem;
void* thread_func(void* data)
{
// 等待信号量
sem_wait(&sem);
// do something
// 发送信号量
sem_post(&sem);
return NULL;
}
int main(int argc, char** argv)
{
pthread_t thread;
// 初始化信号量
sem_init(&sem, 0, 1);
// 创建线程
pthread_create(&thread, NULL, thread_func, NULL);
// 等待信号量
sem_wait(&sem);
// do something
// 发送信号量
sem_post(&sem);
// 等待线程结束
pthread_join(thread, NULL);
// 销毁信号量
sem_destroy(&sem);
return 0;
}
在示例中,我们使用sem_t定义一个信号量sem,通过sem_wait函数等待信号量,通过sem_post函数发送信号量。
四、读写锁(Read-Write Lock)
1. 读写锁概念
读写锁是一种同步机制,与互斥锁类似,不同的是读写锁允许同时有多个读操作,但只能有一个写操作。通常读操作并不会修改数据,而是对数据进行访问和展现,因此可以有多个线程同时进行读操作。pthread_rwlock_t为读写锁类型,可以通过pthread_rwlock_init、pthread_rwlock_rdlock、pthread_rwlock_wrlock、pthread_rwlock_unlock、pthread_rwlock_destroy等函数使用此类型进行相关的操作。
2. 示例
#include <pthread.h>
#include <stdio.h>
pthread_rwlock_t rwlock;
void* read_thread_func(void* data)
{
// 读取锁
pthread_rwlock_rdlock(&rwlock);
// do read
// 释放读锁
pthread_rwlock_unlock(&rwlock);
return NULL;
}
void* write_thread_func(void* data)
{
// 写锁
pthread_rwlock_wrlock(&rwlock);
// do write
// 释放写锁
pthread_rwlock_unlock(&rwlock);
return NULL;
}
int main(int argc, char** argv)
{
pthread_t read_thread, write_thread;
// 初始化读写锁
pthread_rwlock_init(&rwlock, NULL);
// 创建读线程和写线程
pthread_create(&read_thread, NULL, read_thread_func, NULL);
pthread_create(&write_thread, NULL, write_thread_func, NULL);
// 等待读线程和写线程结束
pthread_join(read_thread, NULL);
pthread_join(write_thread, NULL);
// 销毁读写锁
pthread_rwlock_destroy(&rwlock);
return 0;
}
在示例中,我们定义一个读写锁类型rwlock,通过pthread_rwlock_rdlock函数获取读锁,通过pthread_rwlock_wrlock函数获取写锁,通过pthread_rwlock_unlock函数释放锁。在主线程中先创建读线程和写线程,然后等待它们结束,最后销毁读写锁。
五、总结
四种线程同步机制各有特点,应根据具体需求进行选择。如果需要的是最基本的线程同步措施,应选择互斥锁;如果需要等待某个条件,再进行操作,则选择条件变量;如果需要限制并发量,则选择信号量;如果需要多读单写,则选择读写锁。
以上是本文对C++实现线程同步的四种方式的总结。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++实现线程同步的四种方式总结 - Python技术站