互斥锁--NSLock

2024-06-17 02:32
文章标签 互斥 nslock

本文主要是介绍互斥锁--NSLock,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

互斥锁–NSLock

互斥锁主要用于对临界区资源的保护,在多线程编程中防止不同的线程对同一公共资源操作(读或写),当A线程的任务没有执行完毕时(资源被锁住),B线程会进入睡眠状态等待A线程的任务执行完毕,当A程的任务执行完毕,B线程会自动唤醒然后执行任务。iOS中常用的互斥锁有NSLock@synchronizedpthread_mutexNSConditionNSConditionLockNSRecursiveLock。下面我们逐一介绍这几个锁,现在我们先看一下NSLock的相关内容。

1、NSLock

**介绍:**在Fondation库中提供的基本的锁,NSLock继承自NSObject,遵守NSLocking协议,A线程获取锁后,B线程在获取锁时会被系统挂起,知道A线程释放锁,B线程才可以获取锁。它以对象的形式供开发者使用,我们先看一下它的API:

@protocol NSLocking- (void)lock;
- (void)unlock;@end@interface NSLock : NSObject <NSLocking> {
@privatevoid *_priv;
}- (BOOL)tryLock;
- (BOOL)lockBeforeDate:(NSDate *)limit;@property (nullable, copy) NSString *name; 
@end

**注意:**要成对使用NSLock,不要连续锁定,否则会造成死锁,下面的例子就是连续锁定导致死锁。

-(void)methodA
{self.lock = [[NSLock alloc]init];[self.lock lock];//1NSLog(@"1");[self methodB];//2NSLog(@"2");[self.lock unlock];
}-(void)test
{[self.lock lock];NSLog(@"3");[self.lock unlock];
}

最后打印出1,代码已经死锁,因为当前线程运行到1时获取锁并加锁,运行到2时在test方法中再次获取锁加锁,但是test方法中的锁和1中的锁是同样的锁,需等待当前线程解锁,但是当前线程正在执行test方法,test方法等待当前线程释放锁,造成死锁。

解决办法:NSLock是非递归锁,当同一线程重复获取同一非递归锁时,就会发生死锁,可以用递归锁代替NSLock,比如NSRecursiveLock或者@synchronized

2、实现

NSLock锁是对pthread_mutex的简单封装,NSLock的底层实现,是创建一个PTHREAD_MUTEXT_ERRORCHECK类型的pthread_mutex,由于封装时增加了错误核查和提示,会损失一定的性能。从GNUSetup里面的实现我们即可看出NSLock是对pthread_mutex的封装。

  • -init方法使用pthread_mutex_init来初始化一个锁。

  • -lockBeforeDate:方法是一个循环,在时间没有结束前使用pthread_mutex_trylock去检查是否可以获取锁,获取成功返回yes,表示线程可以操作某个资源,如果获取失败提示出错,并且让出资源,让优先级高的线程先获取资源。

/* Use an error-checking lock.  This is marginally slower, but lets us throw* exceptions when incorrect locking occurs.*/
- (id) init
{if (nil != (self = [super init])){if (0 != pthread_mutex_init(&_mutex, &attr_reporting)){DESTROY(self);}}return self;
}- (BOOL) lockBeforeDate: (NSDate*)limit
{do{int err = pthread_mutex_trylock(&_mutex);if (0 == err){CHK(Hold)return YES;}if (EDEADLK == err){(*_NSLock_error_handler)(self, _cmd, NO, @"deadlock");}sched_yield();} while ([limit timeIntervalSinceNow] > 0);return NO;
}

这篇关于互斥锁--NSLock的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1068244

相关文章

java线程深度解析(二)——线程互斥技术与线程间通信

http://blog.csdn.net/daybreak1209/article/details/51307679      在java多线程——线程同步问题中,对于多线程下程序启动时出现的线程安全问题的背景和初步解决方案已经有了详细的介绍。本文将再度深入解析对线程代码块和方法的同步控制和多线程间通信的实例。 一、再现多线程下安全问题 先看开启两条线程,分别按序打印字符串的

Java并发:互斥锁,读写锁,Condition,StampedLock

3,Lock与Condition 3.1,互斥锁 3.1.1,可重入锁 锁的可重入性(Reentrant Locking)是指在同一个线程中,已经获取锁的线程可以再次获取该锁而不会导致死锁。这种特性允许线程在持有锁的情况下,可以递归地调用自身的同步方法或代码块,而不会因为再次尝试获取相同的锁而被阻塞。显然,通常的锁都要设计成可重入的。否则就会发生死锁。 synchronized关键字,就是

三个同步与互斥问题之生产者与消费者

#include<stdio.h> #include<pthread.h> pthread_mutex_t  mutex; #define Max 10 pthread_cond_t pro; pthread_cond_t con; int buffer=0;//全局变量----一开始为0,只有生产者可以执行 void deal_produce(

三个同步与互斥问题之哲学家就餐

#include<stdio.h> #include <semaphore.h> #include<pthread.h> //筷子作为mutex   pthread_mutex_t chopstick[5] ;   int eatnum[5]={5,5,5,5,5}; void *eat_think(void *arg)   {       int i= *(cha

FreeRTOS学习笔记—④RTOS通信管理篇/同步互斥与通信(正在更新中)

二、RTOS的核心功能   RTOS的核心功能块主要分为任务管理、内核管理、时间管理以及通信管理4部分,框架图如下所示:   (1)任务管理:负责管理和调度任务的执行,确保系统中的任务能够按照预期运行。   (2)内核管理:负责系统核心功能的管理,包括内存、中断、异常处理和系统启动等。   (3)时间管理:负责所有与时间相关的操作,包括系统时钟、定时器、任务延迟和周期性任务的执行。   (4)通

Java-互斥锁死锁释放锁

互斥锁         互斥锁(Mutex Lock)是一种同步机制,用于确保在任何时刻只有一个线程可以访问特定的代码段(临界区),从而防止数据竞争和不一致性。 使用方法: 在Java中,可以使用synchronized关键字或ReentrantLock类来实现互斥锁。使用lock()方法获取锁,使用unlock()方法释放锁。 特点: 确保线程安全,防止多个线程同时访问共享资源。简单易

NSLock-多线程中锁的使用

一、NSLock的使用 1、首先看看官方API中对NSLock的一些说明 @protocol NSLocking  lock 方法 - (void)lock 获得锁 unlock 方法 - (void)unlock 释放锁 @interface NSLock lockBeforeDate: 方法 - (B

条件变量:为什么要与互斥锁配套使用?为什么要使用while来避免虚假唤醒?

首先关于条件变量的引入: 假想在这样的情况下,多个线程需要等待某个条件才能继续工作(如生产者消费者模型中,消费者需要等待流水线上有产品后才能消费),如果只使用互拆锁,则多个线程要不停的查询流水线是否为空这个状态,并且查询这个操作需要加入临界区,因为流水线不仅同时有多个消费者,还有生产者在生产,不加锁的话可能出现两个甚至多个消费者对同一个产品动手的情况。这种不停查询的操作是很蠢的,因此引入了条件变

【操作系统】同步互斥与Golang互斥锁实现

【操作系统】同步互斥问题与Golang互斥锁实现 1 背景1.1 独立线程1.2 合作线程1.3 合作有风险,为什么需要合作1.4 多协程并发执行的风险举例(Golang语言)1.5 对风险的思考 2 同步互斥2.1 一些概念2.2 解决方案——保护临界区2.3 禁用硬件中断2.4 纯软件方法2.5 硬件原子操作2.5.1 TestAndSet(TS指令/TSL指令)2.5.2 SWAP