首页 > 其他分享 >iOS中的自旋锁(OSSpinLock)

iOS中的自旋锁(OSSpinLock)

时间:2024-08-15 17:55:24浏览次数:10  
标签:tickets OSSpinLock lock self iOS unfair 线程 自旋 os

目录

​​​​​​​前言

1.概念

一、基本用法

 1.初始化

2.锁定和解锁

二、示例代码

三、os_unfair_lock的优缺点

1.优点

1.防止优先级反转

2.性能高

3.轻量级

2.缺点

1.不支持递归锁定

2.线程杀死时不自动释放


前言

        这篇文章主要介绍下OSSpinLock(自旋锁)。

1.概念

        os_unfair_lock 是 iOS 和 macOS 中的锁定机制,旨在替代已弃用的 OSSpinLock。os_unfair_lock 解决了 OSSpinLock 存在的优先级反转问题,同时保持了较高的性能和低开销。它适用于在多线程环境中保护共享资源,并且是轻量级锁定方案。

一、基本用法

        os_unfair_lock 的 API 非常简单,包含初始化、锁定、解锁等操作。它的使用方式与 OSSpinLock 类似,但具有更好的性能和安全性。

 1.初始化

os_unfair_lock unfairLock = OS_UNFAIR_LOCK_INIT;

2.锁定和解锁

        锁定和解锁的主要API如下:

void os_unfair_lock_lock(os_unfair_lock_t lock);
void os_unfair_lock_unlock(os_unfair_lock_t lock);
bool os_unfair_lock_trylock(os_unfair_lock_t lock);

        os_unfair_lock_lock:获取锁。如果锁已经被其他线程持有,当前线程会被阻塞,直到锁可用。

        os_unfair_lock_unlock:释放锁。

        os_unfair_lock_trylock:尝试获取锁。如果成功,返回 true;如果锁已经被其他线程持有,返回 false。

二、示例代码

        我们可以使用os_fair_lock实现一个买票和卖票的例子。在这个例子中,我们创建了一个票务系统,多个线程进行同时买票和卖票操作,使用os_unfair_lock来保证线程安全。

        以下是一个使用 os_unfair_lock 的简单示例:        

#import <Foundation/Foundation.h>
#import <os/lock.h>

@interface TicketSystem : NSObject

@property (nonatomic, assign) int tickets;
@property (nonatomic, assign) os_unfair_lock lock;

- (instancetype)initWithTicketCount:(int)count;
- (void)sellTicket;
- (void)buyTicket;

@end

@implementation TicketSystem

- (instancetype)initWithTicketCount:(int)count {
    self = [super init];
    if (self) {
        _tickets = count;
        _lock = OS_UNFAIR_LOCK_INIT;
    }
    return self;
}

- (void)sellTicket {
    os_unfair_lock_lock(&_lock);
    if (self.tickets > 0) {
        self.tickets--;
        NSLog(@"Ticket sold. Remaining tickets: %d", self.tickets);
    } else {
        NSLog(@"No tickets left to sell.");
    }
    os_unfair_lock_unlock(&_lock);
}

- (void)buyTicket {
    os_unfair_lock_lock(&_lock);
    if (self.tickets < 100) { // 假设最大票数为100
        self.tickets++;
        NSLog(@"Ticket bought. Total tickets: %d", self.tickets);
    } else {
        NSLog(@"Max tickets reached. Cannot buy more.");
    }
    os_unfair_lock_unlock(&_lock);
}

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        TicketSystem *ticketSystem = [[TicketSystem alloc] initWithTicketCount:50];
        
        // 模拟卖票线程
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            for (int i = 0; i < 30; i++) {
                [ticketSystem sellTicket];
                [NSThread sleepForTimeInterval:0.1]; // 模拟卖票操作的耗时
            }
        });
        
        // 模拟买票线程
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            for (int i = 0; i < 30; i++) {
                [ticketSystem buyTicket];
                [NSThread sleepForTimeInterval:0.15]; // 模拟买票操作的耗时
            }
        });
        
        // 主线程等待一段时间以便子线程完成操作
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]];
    }
    return 0;
}

        在这个示例中,

1. TicketSystem类:

       这个ticketSystem类用来管理票的数量。

        tickets 属性用于记录当前票的数量。

        lock 属性是一个 os_unfair_lock,用于确保 sellTicket 和 buyTicket 方法在多线程环境下的安全性。

2. sellTicket方法:

         该方法模拟了卖票的操作,先加锁,然后检查是否有票,如果有票则减去一张票,并打印当前剩余票数。

        最后释放锁。

3. buyTicket方法:

        该方法模拟了买票的操作,先加锁,然后检查当前票数是否少于最大票数,如果满足条件则加一张票,并打印当前总票数。

        最后释放锁。

4.多线程操作:

        使用 dispatch_async 创建两个并发线程,一个用于模拟卖票,一个用于模拟买票。        

        通过 NSThread sleepForTimeInterval 模拟操作的耗时,确保线程之间的竞争。

5.主线程等待:

        为了让子线程完成操作,主线程使用 NSRunLoop 等待一段时间。

三、os_unfair_lock的优缺点

1.优点

1.防止优先级反转

        os_unfair_lock 解决了 OSSpinLock 中的优先级反转问题,当高优先级线程需要获取锁时,系统会尽快让低优先级线程释放锁。

2.性能高

        os_unfair_lock 在锁竞争较少的情况下具有较高的性能,开销较低。

3.轻量级

        与更复杂的同步机制(如 pthread_mutex)相比,os_unfair_lock 更加轻量,适合需要快速锁定和解锁的场景。

2.缺点

1.不支持递归锁定

        os_unfair_lock 不支持递归锁定(即同一线程多次锁定同一锁)。如果需要递归锁定功能,建议使用其他同步机制,如 NSRecursiveLock。

2.线程杀死时不自动释放

        如果持有锁的线程被强制终止,锁不会自动释放,可能导致死锁。因此,在使用 os_unfair_lock 时需要小心处理线程终止的情况。

        

标签:tickets,OSSpinLock,lock,self,iOS,unfair,线程,自旋,os
From: https://blog.csdn.net/ZCC361571217/article/details/141227729

相关文章

  • 鸿蒙HarmonyOS NEXT:使用axios方法请求实时天气数据
    通过axios方法请求高德天气查询api,实现获取实时天气数据,接下来是实现步骤:模块导入与数据准备:通过以下语句导入了必要的模块和数据:importaxios,{AxiosResponse,AxiosError}from'@ohos/axios'//导入axiosimport{cities}from'./tools/citys';//调用事先存好的城......
  • axios访问后端,及后端返回前端报错跨域问题
    packagecom.example.demo.test.config;importorg.springframework.util.StringUtils;importjavax.servlet.*;importjavax.servlet.annotation.WebFilter;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjav......
  • 苹果在iOS 18.1中向第三方开发者开放iPhone的NFC芯片
    苹果公司今天宣布,开发者很快就能首次在自己的应用程序中提供NFC交易功能,而目前这主要是ApplePay独有的功能。从今年晚些时候的iOS18.1开始,开发者将可以使用新的API提供独立于ApplePay和AppleWallet的应用内非接触式交易。这将为店内支付、车钥匙、交通、企......
  • Nios ll软核处理器
    1.打开软件(1)quartus软件内部打开(2)创建软件快捷方式,桌面打开。软件安装目录文件夹下,nois2eds->bin->eclipse-nios2.exe,创建快捷方式,放到桌面。2.WorkspaceLauncher在工程文件夹下创建NiosII文件夹存放软核工作区3.NiosII-Ecliesp软件保留页面(1)菜单区......
  • 使用 Axios 下载文件并更新进度条
    使用Axios下载文件并更新进度条使用axios的onDownloadProgress回调函数实现下载文件,并更新下载进度条。示例代码import{ElMessage}from"element-plus";importaxiosfrom"axios";importtype{AxiosResponse,AxiosProgressEvent}from"axios";import{baseUrl......
  • iOS LaunchScreen.storyboard启动白屏(不显示)
    最近接手一个项目,启动页用LaunchScreen.storyboard需要修改下启动图发现启动图替换了居然不显示正常的解决方法很简单:需要要加载的图片放在工程的根目录下,不要放到Assets中。结束吐槽下storyboard这东西问题太多尽量还是少用吧。 storyboard设置的图片,如果这图片放在......
  • iOS 仿照TopWidgets 小组件动画
    iOS小组件本身不支持动画,但是像TopWidgets,ColorfulWidget等APP却能实现各种帧动画,播视频.播放Gif,View的平移旋转等.发现其实它们是用了一个私有旋转方法,我将其打包成一个动态库后,可以结合多个View旋转,杠杆原理来实现控件的移动.播放gif动画等.而且亲测上线无问题.D......
  • uniapp+uView安卓与IOS微信与支付宝支付
    页面仅供参考,记录支付流程处理方法:<template> <viewclass="pay-order-page">  <viewclass="content-box"style="padding-bottom:14rpx;">   <viewclass="tip-box"v-if="detail.purchaseLimitNum>0&qu......
  • iOS 仿照TopWidgets 小组件动画
    iOS仿照TopWidgets小组件动画iOS小组件本身不支持动画,但是像TopWidgets,ColorfulWidget等APP却能实现各种帧动画,播视频.播放Gif,View的平移旋转等.发现其实它们是用了一个私有旋转方法,我将其打包成一个动态库后,可以结合多个View旋转,杠杆原理来实现控件的移动.......
  • IOS UI自动化脚本
    1.安装rethinkdbhttps://rethinkdb.com/docs/install/osx/2.安装bunch包错修复setup.py里面的数据,去掉U3.imp包变成了importlib需要替换  importImp#moduleFile,pathName,desc=imp.find_module(moduleName,[os.path.dirname(modulePath)])#module=imp.load_m......