线程同步

线程同步

  在没有线程这一概念的系统中,进程同时是可拥有资源和可独立调度及分派的基本单位。当引入线程概念之后,进程仅仅是可拥有资源的基本单位,而线程成为了可独立调度及分派的基本单位。这使得对于同一个进程的多个线程而言,它们将共享着同一地址空间、全局变量、文件等内容,方便了线程之间的通信、合作。但是这也需要让我们注意由于同步造成的一些老问题。

互斥量

  互斥量可以确保某一资源/数据在某一时刻仅被一个线程所访问。要定义互斥量可以使用如下函数:

#include <pthread.h>

int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);

  互斥量是一个pthread_mutex_t类型的变量,使用pthread_mutex_init函数可对互斥量进行初始化(其中第二个参数attr是互斥量属性,可设置为NULL);使用pthread_mutex_destroy则可销毁互斥量。

  互斥量可以理解为一把锁,即互斥量至少要有上锁和解锁两个状态。当某一线程要访问共享资源时就需要以下过程:

  1. 等待互斥量mutex处于解锁状态(如果是第一个访问共享资源的当然就不用这个等待的步骤了)
  2. 将互斥量mutex设置为上锁状态
  3. 访问共享资源
  4. 结束访问,将互斥量mutex设置为解锁状态

  有关设置互斥量状态的函数如下:

#include <pthread.h>

int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_trylock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

其中lock用于上锁、unlock用于解锁。当对一个已经上锁的mutex使用lock,则该线程将会被阻塞(实际上阻塞都是自己阻塞自己,所以说 ‘被’ 感觉不太好),直到mutex被解锁。但是,如果不想让线程进入阻塞态,则可以使用trylock,相当于不断地尝试上锁。

读写锁

  读写锁是另一种类型的锁。如果说互斥量是只有两种状态的锁(上锁状态和解锁状态),读写锁就有三种状态:解锁状态、读模式上锁状态、写模式上锁状态。

  • 当一个进程以写模式为读写锁上锁时,读写锁就处于写模式上锁状态。此时上锁的线程可以以写模式访问资源,而其它任何线程一旦尝试对读写锁上锁就进入阻塞态。
  • 当一个进程以读模式为读写锁上锁时,读写锁就处于读模式上锁状态。此时上锁的线程可以以读模式访问资源,并且其它任何读线程都可以对该读写锁继续上锁,但任何写进程一旦尝试对读写锁上锁就进入阻塞态直到所有读线程解锁。
  • 解锁状态就是没有任何线程访问共享资源的状态。

  读写锁就是解决读者-写者问题的锁。一个资源同一时刻只能被一个写者写,并且写的同时不能有读者来读;一个资源在同一时刻可以被多个读者读,但读的同时不能有写者写。

读写锁相关的函数:

#include <pthread.h>
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); //尝试设置为读模式上锁状态

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); //尝试设置为写模式上锁状态

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock); //设置为解锁状态
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值