避免信号量出现死锁

You might well be familar with GCD, but what if you wish to make sure that you never enter a deadlocked state?

您可能非常熟悉GCD ,但是如果您希望确保自己从未进入僵持状态怎么办?

Read on!

继续阅读!

Difficulty: Beginner | Easy | Normal | Challenging

难度:初学者| 容易| 普通 | 具有挑战性的

This article has been developed using Xcode 11.4.1, and Swift 5.2.2

本文是使用Xcode 11.4.1和Swift 5.2.2开发的。

Updated for Xcode 11.5

为Xcode 11.5更新

重要性 (The importance)

The Readers-Writers Problem is an important one in Computer Science.

读者-作家问题是计算机科学中的重要问题

In your iOS application you may have several threads that wish to access a shared resource (the cannonical example for this is a file).

在您的iOS应用程序中,您可能有多个线程希望访问共享资源(此文件的典型示例是文件)。

Image for post
Photo by Maksym Kaharlytskyi on Unsplash
Maksym Kaharlytskyi在Unsplash上​​拍摄的照片

You would not want to be in a situation where the file can be written on at the same time as it is being read — imagine that *during* the reading process the file is written. This would mean that we couldn’t be certain of what we were reading; perhaps half of the original file and half of the updated file — what a disaster!

您不希望处于可以在读取文件的同时写入文件的情况–假设* *读取过程中写入了文件。 这意味着我们无法确定正在阅读的内容。 可能只有原始文件的一半,而更新文件的一半—真是一场灾难!

Image for post
Photo by Sarah Kilian on Unsplash
莎拉·基利安(Sarah Kilian)在Unsplash上​​摄

实际例子 (The practical example)

For each of these examples two `queues` are going to be used as follows:

对于这些示例中的每一个,将使用以下两个“队列”:

Image for post
Click for Gist 单击要点

now if you wish to follow along in Playgrounds you’ll need to import PlaygroundSupport and add the indefiniteExecution line PlaygroundPage.current.needsIndefiniteExecution = true.

现在,如果您希望在Playgrounds中继续学习 ,则需要import PlaygroundSupport并添加indefiniteExecution行PlaygroundPage.current.needsIndefiniteExecution = true

With that said, we can then create a naive function that attempts to write to the console from both queues (which usually use a single thread each, but this is not guarenteed):

话虽如此,我们然后可以创建一个朴素的函数,尝试从两个队列(通常每个队列使用一个线程,但这都不保证)写入控制台:

Image for post
Click for Gist 单击要点

now depending on your machine, what is going on in the world and other indecipherable variables you “might” get all of the userInteractive work items complete before the default priority items.

现在,取决于您的计算机,世界上正在发生的事情以及您“可能”会遇到的其他难以理解的变量,可以使所有userInteractive工作项在default优先级项之前完成。

Image for post
Image for post
A sample output
样本输出

But this isn’t guarenteed. This isn’t a good state to be in — and what if we must have User finished before Default?

但这并不能保证 。 这不是一个好状态-如果我们必须在“ Default之前完成“ User ,该怎么办?

天真的解决方案 (The naive solution)

To control access (in this case printing to the console) be could block access using a Boolean. No problem!

为了控制访问(在这种情况下为打印到控制台),可以使用布尔值来阻止访问。 没问题!

Image for post
Click for Gist 单击要点

But there is a problem

但有个问题

Image for post
The problem
问题

We aren’t guaranteed that we are using the same thread when we access the function. Poor stuff!

我们不能保证在访问函数时使用相同的线程。 可怜的东西!

This will *never* pass code review my friend!

这将* 永远 * 不会通过密码检查我的朋友!

解决方案:信号量 (The solution: A semaphore)

A semaphore limits the amount of concurrent work that can be completed at the same time.

semaphore限制了可以同时完成的并发工作量。

理论信号量 (The theoretical semaphore)

A semaphore simply keeps a count (positive) and contains two operations which must be thread-safe as it empties a queue of threads awaiting the resource in question.

semaphore仅保留一个计数(正数),并包含两个必须是线程安全的操作,因为它清空了等待相关资源的线程队列。

  • wait: If the value is >0, decrement else block

    等待:如果值> 0,则减量else块
  • signal: If threads are waiting then unblock one, else increment the value

    信号:如果线程正在等待,则解除阻塞,否则增加该值

When we set up a semaphore we pass a an initial value to the Semaphone — in this example we will use 1.

设置信号量时,我们将一个初始值传递给信号量–在本示例中,我们将使用1。

Image for post
performwork 表演工作

So semaphore.wait enables waiting for the resource to become avaliable, and then releases with semaphore.signal()

因此, semaphore.wait允许等待资源可用,然后使用semaphore.signal()释放

Image for post

That’s more like it!

这还差不多!

结论 (Conclusion)

So a semaphore provides nothing more than a variable that can be incremented and decremented in a thread-safe manner. By helping you manage a multithreaded environment, a semaphore helps you manage complexity — and even provide an easy to use public API to build.

因此, semaphore提供一个可以以线程安全的方式递增和递减的变量。 通过帮助您管理多线程环境, semaphore可以帮助您管理复杂性-甚至提供易于使用的公共API进行构建。

Now you’ve got the tool, what are you waiting for?

现在您已经有了该工具,您还在等什么呢?

If you’ve any questions, comments or suggestions please hit me up on Twitter

如果您有任何疑问,意见或建议,请在Twitter上打我

Why not sign up to my newsletter

为什么不注册我的时事通讯

翻译自: https://medium.com/@stevenpcurtis.sc/avoid-deadlock-with-semaphores-36bb879d73ae

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值