gpt4 book ai didi

ios - 关于使这个线程安全但高效的建议?

转载 作者:行者123 更新时间:2023-11-28 18:38:46 25 4
gpt4 key购买 nike

我一直在思考一个看起来很容易实现的问题,但一个高效且线程安全的解决方案却阻碍了我。我想要做的是创建某种工作对象。多个调用者可能会要求它在不同的线程中工作。一个要求是请求不能排队。换句话说,如果有人要求 worker 工作但看到它已经在工作,它应该早点返回。

一个简单的第一步是这样的:

@interface Worker : NSObject
@property (nonatomic, assign, getter = isWorking) BOOL working;
- (void)doWork;
@end

@implementation Worker
{
dispatch_queue_t _workerQueue; //... a private serial queue
}

- (void)doWork
{
if ( self.isWorking )
{
return;
}
self.working = YES;
dispatch_async(_workerQueue, ^{
// Do time consuming work here ... Done!
self.working = NO;
});
}
@end

问题在于 isWorking 属性不是线程安全的。将其标记为原子在这里无济于事,因为对它的访问需要在几个语句之间同步。

为了使其成为线程安全的,我需要使用锁来保护 isWorking:

@interface Worker : NSObject
@property (nonatomic, assign, getter = isWorking) BOOL working;
- (void)doWork;
@end

@implementation Worker
{
dispatch_queue_t _workerQueue; //... a private serial queue
NSLock *_lock; // assume this is created
}

- (void)doWork
{
[_lock lock];
if ( self.isWorking )
{
[_lock unlock];
return;
}
self.working = YES;
[_lock unlock];
dispatch_async(_workerQueue, ^{
// Do time consuming work here ... Done!
[_lock lock];
self.working = NO;
[_lock unlock];
});
}

@结束

虽然我确实相信这会是线程安全的,但我认为必须如此频繁地获取和放弃锁(一项昂贵的操作)是非常糟糕的。

那么,有没有更优雅的方案呢?

最佳答案

dispatch_semaphore is the idiomatic way to limit access to a finite resource ,如果您已经在使用 GCD。

// Add an ivar:
dispatch_semaphore_t _semaphore;

// To initialize:
_semaphore = dispatch_semaphore_create(1);

// To "do work" from any thread:
- (void)doWork
{
if (dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_NOW) == 0) {
// We got the semaphore without waiting, so we're first in line.
dispatch_async(_workerQueue, ^{
// do time consuming work here, then when done:
dispatch_semaphore_signal(_semaphore);
});
} else {
// We would have had to wait for the semaphore, so somebody must have
// been doing work already, and we should do nothing.
}
}

Here's a blog post explaining in more detail.

关于ios - 关于使这个线程安全但高效的建议?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14251858/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com