创建初始值为 0 的信号量会导致执行出现问题
Creating semaphore with initial value of 0 make issues with execution
我正在学习 GCD,遇到了有关信号量的问题。
这是我的代码:
class ViewController: UIViewController {
var semaphore: dispatch_semaphore_t! = nil
override func viewDidLoad() {
super.viewDidLoad()
semaphore = dispatch_semaphore_create(0)
dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)) {
print("Entering")
self.semaphoreTask()
print(self.semaphore.debugDescription)
}
semaphoreTask()
print(semaphore.debugDescription)
}
func semaphoreTask() {
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
for i in 0...1000 {
print(i)
if i == 1000 {
print("i is equal to 10000!")
}
}
dispatch_semaphore_signal(self.semaphore)
}
如果我 运行 这段代码,那么控制台中不会打印任何来自 semaphoreTask 的内容,但是如果我更改
semaphore = dispatch_semaphore_create(0)
至
semaphore = dispatch_semaphore_create(1)
一切开始顺利。
问题是为什么要写dispatch_semaphore_create(1)而不是0?
谢谢!
您可以通过两种不同的方式使用信号量:
- 表示工作或资源何时准备就绪。
在这种情况下,您从 0 开始信号量。创建者在准备就绪时调用
signal
。消费者调用 wait
等待预期的项目/资源。
- 限制并发操作/请求/使用的数量。
在这种情况下,您以正值启动信号量,例如 4。每个用户都调用
wait
,如果资源可用,则允许他们继续。如果不是,它们将被阻止。当每个人都完成他们调用的资源时 signal
.
所以,您所看到的是预期的,因为您将信号量设置为就绪标志,但将其用作访问限制(因为您先调用 wait
)。
所以我更正了我的代码以向您展示我是如何修复它的(感谢@Wain)。
class ViewController: UIViewController {
var semaphore: dispatch_semaphore_t! = nil
override func viewDidLoad() {
super.viewDidLoad()
semaphore = dispatch_semaphore_create(0)
dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)) {
print("Entering")
self.semaphoreTask()
}
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
semaphoreTask()
}
func semaphoreTask() {
print(semaphore.debugDescription)
for i in 0...1000 {
print(i)
if i == 1000 {
print("i is equal to 10000!")
}
}
dispatch_semaphore_signal(self.semaphore)
}
}
我正在学习 GCD,遇到了有关信号量的问题。 这是我的代码:
class ViewController: UIViewController {
var semaphore: dispatch_semaphore_t! = nil
override func viewDidLoad() {
super.viewDidLoad()
semaphore = dispatch_semaphore_create(0)
dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)) {
print("Entering")
self.semaphoreTask()
print(self.semaphore.debugDescription)
}
semaphoreTask()
print(semaphore.debugDescription)
}
func semaphoreTask() {
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
for i in 0...1000 {
print(i)
if i == 1000 {
print("i is equal to 10000!")
}
}
dispatch_semaphore_signal(self.semaphore)
}
如果我 运行 这段代码,那么控制台中不会打印任何来自 semaphoreTask 的内容,但是如果我更改
semaphore = dispatch_semaphore_create(0)
至
semaphore = dispatch_semaphore_create(1)
一切开始顺利。
问题是为什么要写dispatch_semaphore_create(1)而不是0?
谢谢!
您可以通过两种不同的方式使用信号量:
- 表示工作或资源何时准备就绪。
在这种情况下,您从 0 开始信号量。创建者在准备就绪时调用
signal
。消费者调用wait
等待预期的项目/资源。 - 限制并发操作/请求/使用的数量。
在这种情况下,您以正值启动信号量,例如 4。每个用户都调用
wait
,如果资源可用,则允许他们继续。如果不是,它们将被阻止。当每个人都完成他们调用的资源时signal
.
所以,您所看到的是预期的,因为您将信号量设置为就绪标志,但将其用作访问限制(因为您先调用 wait
)。
所以我更正了我的代码以向您展示我是如何修复它的(感谢@Wain)。
class ViewController: UIViewController {
var semaphore: dispatch_semaphore_t! = nil
override func viewDidLoad() {
super.viewDidLoad()
semaphore = dispatch_semaphore_create(0)
dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)) {
print("Entering")
self.semaphoreTask()
}
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
semaphoreTask()
}
func semaphoreTask() {
print(semaphore.debugDescription)
for i in 0...1000 {
print(i)
if i == 1000 {
print("i is equal to 10000!")
}
}
dispatch_semaphore_signal(self.semaphore)
}
}