我的程序是一个处理传入请求的服务器.每个有效请求都被包装NSOperation
并传递给法线NSOperationQueue
.
每个都NSOpearation
处理它的请求.在某些情况下,NSDictionary
我使用dispatch_queue
(并发队列),dispatch_barrier_async
(当设置值时)和dispatch_sync
(当获取值时)存在争用,以使此NSDictionary
线程安全.
我同时用100个请求测试我的程序,然后该过程有时冻结.我用SIGSEGV
查看崩溃日志来终止进程.
大多数线程都停留在dispatch_sync
此队列中.下面有一张纸条
达到调度线程软限制:64(同步操作中阻塞的调度线程太多)
这个音符到底意味着什么?它的行为是什么?我找不到有关此限制的信息.我该如何解决这个问题?
我可以想出两种可能的方法来避免这个问题.(我将测试它们并稍后更新)
dispatch_semaphore
限制块提交给该并发队列.maxConcurrentOperationCount
的NSOperationQueue
你有更好的解决方案吗?
我得到了三个名为queueA,queueB,queueC的调度线程。
现在,我希望在执行queueB和queueC之后执行queueA。
所以我尝试通过实现它DispatchSemaphore
。
我的问题是:一次在线程中两次
调用wait()
以使信号量2安全吗?
self.semaphore.wait() // +1
self.semaphore.wait() // +1
Run Code Online (Sandbox Code Playgroud)
以下是完整的测试代码:
class GCDLockTest {
let semaphore = DispatchSemaphore(value: 0)
func test() {
let queueA = DispatchQueue(label: "Q1")
let queueB = DispatchQueue(label: "Q2")
let queueC = DispatchQueue(label: "Q3")
queueA.async {
self.semaphore.wait() // +1
self.semaphore.wait() // +1
print("QueueA gonna sleep")
sleep(3)
print("QueueA woke up")
}
queueB.async {
self.semaphore.signal() // -1
print("QueueB gonna sleep")
sleep(3)
print("QueueB woke up")
}
queueC.async {
self.semaphore.signal() // -1
print("QueueC gonna sleep") …
Run Code Online (Sandbox Code Playgroud) 我正在Swift 3中创建一个服务器端应用程序.我选择了libevent来实现网络代码,因为它是跨平台的并且不会遇到C10k问题.Libevent实现了它自己的事件循环,但我想保持CFRunLoop和GCD(DispatchQueue.main.after
等)功能,所以我需要以某种方式粘贴它们.
这就是我想出的:
var terminated = false
DispatchQueue.main.after(when: DispatchTime.now() + 3) {
print("Dispatch works!")
terminated = true
}
while !terminated {
switch event_base_loop(eventBase, EVLOOP_NONBLOCK) { // libevent
case 1:
break // No events were processed
case 0:
print("DEBUG: Libevent processed one or more events")
default: // -1
print("Unhandled error in network backend")
exit(1)
}
RunLoop.current().run(mode: RunLoopMode.defaultRunLoopMode,
before: Date(timeIntervalSinceNow: 0.01))
}
Run Code Online (Sandbox Code Playgroud)
这有效,但引入了0.01秒的延迟.当RunLoop正在休眠时,libevent将无法处理事件.当应用程序空闲时,降低此超时会显着增加CPU使用率.
我也在考虑只使用libevent,但是项目中的第三方库可以在内部使用dispatch_async,因此这可能会有问题.
在另一个线程中运行libevent的循环会使同步变得更加复杂,这是解决此延迟问题的唯一方法吗?
LINUX更新.上面的代码在Linux上不起作用(2016-07-25-a Swift snapshot),RunLoop.current().run
存在错误.下面是一个工作的Linux版本,重新实现了计时器和dispatch_main
.它遇到了相同的延迟问题:
let queue = dispatch_get_main_queue()
let timer = …
Run Code Online (Sandbox Code Playgroud) network-programming libevent grand-central-dispatch swift swift3
在选择要运行的队列dispatch_async
时,dispatch_get_global_queue
会提到很多.这是一个特殊的后台队列,它将任务委托给某个线程吗?它几乎是一个单身人士吗?
因此,如果我总是将该队列用于我的dispatch_async
调用,那么该队列是否会变满并且必须等待其他事情才能启动,或者是否可以将其他任务分配给不同的线程?
我想我有点困惑,因为当我选择队列时NSOperation
,我可以选择主线程的队列[NSOperationQueue mainQueue]
,这似乎是同义词,dispatch_get_main_queue
但我在印象背景队列下NSOperation
不得不单独制作实例NSOperationQueue
但是GCD有一个背景队列单例?(dispatch_get_global_queue
)
此外 - 愚蠢的问题,但想确保 - 如果我将一个任务放入队列,队列被分配给一个线程,对吧?如果任务足够大,它就不会在多个线程上拆分,是吗?
multithreading objective-c nsoperation grand-central-dispatch ios