是否有一个“问题”;“公平”;iOS的同步机制

是否有一个“问题”;“公平”;iOS的同步机制,ios,synchronization,Ios,Synchronization,我有一个应用程序,它倾向于在后台线程中执行大量DB活动(下载大型数据库更新),而且这个过程经常会“饿死”UI线程——我知道DB会每隔一段时间释放,但使用的@synchronized机制并不“公平”并允许后台线程立即重新获取锁 是否有另一种机制可以替代,它是合理有效且支持良好的(并且不太难改造)(和“公平的”)机制?正如我在underestand@synchronized中所说的那样。不一定要“公平” 我建议你读一下。将所有需要完成的工作放在队列中有很多有趣的事情(队列应该提供更好的资源共享)。如

我有一个应用程序,它倾向于在后台线程中执行大量DB活动(下载大型数据库更新),而且这个过程经常会“饿死”UI线程——我知道DB会每隔一段时间释放,但使用的
@synchronized
机制并不“公平”并允许后台线程立即重新获取锁


是否有另一种机制可以替代,它是合理有效且支持良好的(并且不太难改造)(和“公平的”)机制?

正如我在underestand@synchronized中所说的那样。不一定要“公平”


我建议你读一下。将所有需要完成的工作放在队列中有很多有趣的事情(队列应该提供更好的资源共享)。

如果您担心阻塞UI线程,可以为数据库操作创建一个串行调度队列。这将使您能够将UI线程中的某些DB操作排队,而不会阻塞它(工作块将被复制到堆中,存储到轮到它被处理为止)

例如,从UI线程,您可以:

database_queue = dispatch_queue_create("com.example.queue", NULL);

dispatch_async(database_queue, ^{
    // Operations on the DB here
});
// The UI will continue responding immediately after here...
队列将一次一个地处理每个块,提供您需要的同步-您只需确保所有DB操作都从该队列中完成

如果确实需要等待工作完成,则可以在这些特定实例中将异步调用替换为同步调用:

dispatch_sync(database_queue, ^{
    ....
    ....

我无法复制你的问题。这里我有一个基于
@synchronized
和pthreads的简单程序(尽管在mac上运行),它清楚地表明
@synchronized
可以按预期工作,假设您释放锁:

void *backgroundThread(void *data)
{
    while (true)
    {
        @synchronized (globalMutex)
        {
            usleep(USEC_PER_SEC / 3);
        }
    }

    return NULL;
}

int main()
{
    pthread_t bgThread = NULL;
    globalMutex = [NSObject new];

    pthread_create(&bgThread, NULL, &backgroundThread, NULL);

    NSTimeInterval lastTime = [[NSDate date] timeIntervalSinceReferenceDate];
    while (true)
    {
        @synchronized (globalMutex)
        {
            NSTimeInterval elapsed = [[NSDate date] timeIntervalSinceReferenceDate] - lastTime;
            NSLog(@"Main Thread 'came up for air' after %lf seconds", elapsed);

            lastTime += elapsed;
        }
    }
}
输出:

TestProj[1494:303] Main Thread 'came up for air' after 0.000015 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.003136 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.000637 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.000610 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.000697 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.000576 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.000571 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.337343 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.335533 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.335253 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.335309 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.335367 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.335223 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.335754 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.335271 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.335211 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.334555 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.335245 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.335203 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.335262 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.335252 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.335667 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.335278 seconds TestProj[1494:303] Main Thread 'came up for air' after 0.335309 seconds TestProj[1494:303]主线程在0.000015秒后“出现空气” TestProj[1494:303]主线程在0.003136秒后“出现空气” TestProj[1494:303]主线程在0.000637秒后“出现空气” TestProj[1494:303]主线程在0.000610秒后“出现空气” TestProj[1494:303]主线程在0.000697秒后“出现空气” TestProj[1494:303]主线程在0.000576秒后“出现空气” TestProj[1494:303]主线程在0.000571秒后“出现空气” TestProj[1494:303]主线程在0.337343秒后“出现空气” TestProj[1494:303]主线程在0.335533秒后“出现空气” TestProj[1494:303]主线程在0.335253秒后“出现空气” TestProj[1494:303]主线程在0.335309秒后“出现空气” TestProj[1494:303]主线程在0.335367秒后“出现空气” TestProj[1494:303]主线程在0.335223秒后“出现空气” TestProj[1494:303]主线程在0.335754秒后“出现空气” TestProj[1494:303]主线程在0.335271秒后“出现空气” TestProj[1494:303]主线程在0.335211秒后“出现空气” TestProj[1494:303]主线程在0.334555秒后“出现空气” TestProj[1494:303]主线程在0.335245秒后“出现空气” TestProj[1494:303]主线程在0.335203秒后“出现空气” TestProj[1494:303]主线程在0.335262秒后“出现空气” TestProj[1494:303]主线程在0.335252秒后“出现空气” TestProj[1494:303]主线程在0.335667秒后“出现空气” TestProj[1494:303]主线程在0.335278秒后“出现空气” TestProj[1494:303]主线程在0.335309秒后“出现空气”
因此,除非您没有正确地释放锁,
@synchronized
正是您在此场景中需要的。请详细说明同步代码的实际外观,以便我们能为您提供更多帮助。

公平锁的确切定义是什么?一般来说,互斥锁作为一个队列工作——无论哪个线程请求访问,都会首先获得它。在这个场景中还有多少线程在运行?如果只有两个,那么就没有什么可以做的了。您是否正在围绕SQLite进行自己的锁定?据我所知,你不需要这样做,因为它是在iOS上用多线程编译的,但是如果我错了,如果有人指出一些关于它的信息,我会很高兴:)@JoachimIsaksson-你错了。SQLite只通过锁定单个操作来保护自己不受破坏性并发的影响。事务锁定等由用户决定。如果您尝试在锁定的数据库上执行操作,则会得到一个难以处理的错误。@RichardJ.RossIII--有两个线程。问题是,UI线程有时会被锁定数分钟,即使DB线程每5秒“启动”。鉴于后台的不同操作可以运行数分钟,在UI线程上运行它们是不可行的。这不是在UI线程上运行它们。队列维护自己的线程,在该线程上完成工作-您只需将工作从UI线程传递到队列,这是一种快速、无阻塞的操作。它不会破坏你的UI。但是我需要在DB后台工作和对DB的UI线程访问之间进行联锁。这就是需要同步的原因。只有一个后台线程,因此后台处理的各个部分之间没有冲突。如果是这种情况,除了找到一种不阻止UI线程(例如分派方法)的方法,然后在工作完成之前显示UIActivityIndicator之外,您无能为力。。至少这会给用户一些反馈,而不是给他们一个没有响应的应用程序。您可以尝试的另一件事是,在后台线程完成锁定后,使其屈服(),从而使UI线程有更多机会在后台线程再次执行之前抓住它。
@synchronized
隐藏了太多的机制,因此非常灵活。不知道是锁的最后一个实例还是堆叠的,无法控制解锁等等。是的,我也无法复制它,直到我可以。我怀疑这是与stor一起发生的