长春建站,网站整站优化推广方案,wordpress账号注册,微博营销网站文章目录 前言一、读写锁二、条件变量总结 前言 一、读写锁
多线程同步机制中的读写锁#xff08;Read-Write Lock#xff09;是一种特殊的锁机制#xff0c;用于控制对共享资源的读写访问。读写锁允许多个线程同时读取共享资源#xff0c;但在写操作时需要独占访问。
读… 文章目录 前言一、读写锁二、条件变量总结 前言 一、读写锁
多线程同步机制中的读写锁Read-Write Lock是一种特殊的锁机制用于控制对共享资源的读写访问。读写锁允许多个线程同时读取共享资源但在写操作时需要独占访问。
读写锁的基本原则是多个线程可以同时获取读锁但只有一个线程可以获取写锁。当有线程持有写锁时其他线程无法获取读锁或写锁直到写操作完成并释放写锁。
读写锁有两种状态读模式下加锁状态读锁写模式下加锁状态写锁。读写锁只有一把。
1. 读写锁的特性 写独占读共享。
读写锁是 “ 写模式加锁 ” 时解锁前所有对该锁加锁的线程都会被阻塞。读写锁是 “ 读模式加锁 ” 时如果线程以读模式 则对其加锁会成功如果线程是以写模式加锁会阻塞。读写锁是 “ 读模式加锁 ” 时既有试图以写模式加锁的线程也有试图以读模式加锁的线程。那么读写锁会阻塞读模式请求。优先满足写模式加锁。读写锁并行阻塞写锁优先级高。
2. 读写锁相关函数
初始化pthread_rwlock_init。获取读锁使用pthread_rwlock_rdlock函数获取读锁。获取写锁使用pthread_rwlock_wrlock函数获取写锁。释放锁使用pthread_rwlock_unlock函数释放读锁或写锁。销毁读写锁在不再需要时使用pthread_rwlock_destroy函数销毁读写锁。
3. 示例代码 下面代码设置一个写进程 和 三个读进程区访问共享资源。
(void*)i 将整数 i 转换为 void* 类型。在线程的函数中需要将其转换回整数类型以便使用它。可以使用 (int)arg 将 void* 转换回 int 类型。void* 是一种通用的泛型指针可以在不关心具体类型的情况下进行转换和操作。
#include stdio.h
#include stdlib.h
#include pthread.h
#include time.h
#include unistd.hpthread_rwlock_t rwlock PTHREAD_RWLOCK_INITIALIZER; // 初始化读写锁int data 1;void *write_thread (void *arg)
{while(1){pthread_rwlock_wrlock(rwlock);data 1;printf(write : data %d\n,data); pthread_rwlock_unlock(rwlock);sleep(rand() %3); // 随机休眠让出 cpu资源}pthread_exit(NULL);
}void *read_thread (void *arg)
{int i (int )arg;while(1){pthread_rwlock_rdlock(rwlock);printf(read %d : data %d\n,i, data); pthread_rwlock_unlock(rwlock);sleep(rand() %3);}pthread_exit(NULL);
}int main(void)
{pthread_t r_tid[5], w_tid;srand(time(NULL));// 创建多个读线程for (int i 0; i 3; i) {pthread_create(r_tid[i], NULL, read_thread, (void*)i);}pthread_create(w_tid, NULL, write_thread, NULL);for(int j0;j3;j)pthread_join(r_tid[j],NULL);pthread_join(w_tid,NULL);pthread_rwlock_destroy(rwlock);return 0;
}二、条件变量
在多线程编程中条件变量是一种用于线程之间进行通信和同步的机制。条件变量允许一个线程等待特定的条件发生并在条件满足时通知其他线程继续执行。条件变量本身不是锁。条件变量常与互斥锁mutex结合使用以实现线程之间的同步操作。
1. 相关函数
(1) 对条件变量进行初始化并可指定属性。通常使用默认属性可以传入 NULL。 int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);(2) 销毁条件变量释放相关资源。
int pthread_cond_destroy(pthread_cond_t *cond);当前线程等待条件变量满足并释放关联的互斥锁。该函数会阻塞线程直至条件变量被通知。 在调用 pthread_cond_wait() 之前必须先获得与条件变量关联的互斥锁 mutex 的锁然后该函数会自动释放 mutex 的锁自动 unlock并让线程进入等待状态直到被另一个线程通过 pthread_cond_signal() 或 pthread_cond_broadcast() 唤醒(自动 lock)。
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);(3) 通知等待在条件变量上的一个线程使其继续执行。如果有多个线程等待只通知其中一个线程。
int pthread_cond_signal(pthread_cond_t *cond);(4) 通知所有等待在条件变量上的线程使它们都继续执行。
int pthread_cond_broadcast(pthread_cond_t *cond) ;2. 示例代码 描述生产者 和 消费者的关系。
#include stdio.h
#include pthread.h
#include stdlib.h
#include unistd.hstruct msg
{int num;struct msg* pnext;
};struct msg *head NULL;pthread_mutex_t mutex PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond PTHREAD_COND_INITIALIZER;void *producer_thread (void *arg) // 生产者线程
{while(1){ struct msg *info malloc(sizeof(struct msg));info-num rand() % 1000 1;pthread_mutex_lock(mutex);info-pnext head;head info;pthread_mutex_unlock(mutex);// 唤醒阻塞的线程pthread_cond_signal(cond); printf(--------------------- producer : %d\n,info-num);sleep(rand() % 3);}return NULL;
}void *customer_thread (void *arg) // 消费者线程
{while(1){struct msg *info; pthread_mutex_lock(mutex);if(head NULL){pthread_cond_wait(cond, mutex); // 阻塞线程等待有数据。}info head;head info-pnext;pthread_mutex_unlock(mutex);printf(customer : %d\n,info-num);free(info);info NULL;sleep(rand() % 3);}return NULL;
}int main(void)
{pthread_t pid,cid;srand(time(NULL)); // 设置随机种子int ret pthread_create(pid, NULL, producer_thread, NULL);if(ret ! 0){printf(prodecer_thread_create error\n);}ret pthread_create(cid, NULL, customer_thread, NULL);if(ret ! 0){printf(consumer_thread_create error\n);}pthread_join(pid, NULL); // 等待回收线程获取退出线程的状态pthread_join(cid, NULL);pthread_mutex_destroy(mutex);pthread_cond_destroy(cond);return 0;
}总结