我期待到多线程,和GCD似乎是一个很大比使用手工编写的解决方案更好的选择pthread.h和pthreads-win32.然而,虽然看起来libdispatch要么正在开发,要么很快就要开始工作,大多数新的POSIX兼容系统......我不得不问,Windows呢?libdispatch移植到Windows 的可能性有多大?阻止这种情况发生的障碍是什么?
如果它归结为它,我需要做什么来预成型portage?
编辑:我已经知道的一些事情,以便开始讨论:
pthread.h用户空间中的所有依赖项libdispatch吗?或者,或者,使用pthreads-win32我想...编辑1:我听说这是完全和完全不可能的,因为libdispatch依赖(某种程度上)kqueue,在Windows上无法提供...有人知道这是真的吗?
windows multithreading portability libdispatch grand-central-dispatch
在Apple的并发编程指南的迁移远离线程部分中,有
改变生产者 - 消费者实现,声称可以使用GCD简化典型的多步骤pthread互斥+条件变量实现.
使用调度队列,您可以将生产者和消费者实现简化为单个调用:
dispatch_async(queue, ^{
// Process a work item.
});
Run Code Online (Sandbox Code Playgroud)
当您的生产者要完成工作时,它所要做的就是将该工作添加到队列中并让队列处理该项目.
生产者 - 消费者问题也被称为有界缓冲问题,但上面没有提到缓冲区,它的边界或消费者,更不用说阻止生产者和消费者以避免过度/不足的运行.
这怎么可能是一个有效的解决方案?
macos multithreading producer-consumer grand-central-dispatch ios
我正在将我的代码从常规GCD移动到NSOperationQueue因为我需要一些功能.我的很多代码都依赖于dispatch_after才能正常工作.有没有办法做类似的事情NSOperation?
这是我需要转换为的一些代码NSOperation.如果您可以提供使用此代码转换它的示例,那就太棒了.
dispatch_queue_t queue = dispatch_queue_create("com.cue.MainFade", NULL);
dispatch_time_t mainPopTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeRun * NSEC_PER_SEC));
dispatch_after(mainPopTime, queue, ^(void){
if(dFade !=nil){
double incriment = ([dFade volume] / [self fadeOut])/10; //incriment per .1 seconds.
[self doDelayFadeOut:incriment with:dFade on:dispatch_queue_create("com.cue.MainFade", 0)];
}
});
Run Code Online (Sandbox Code Playgroud) xcode objective-c nsoperationqueue grand-central-dispatch ios
我想将给定的块添加到数组中,然后在请求时运行数组中包含的所有块.我有类似这样的代码:
class MyArrayBlockClass {
private var blocksArray: Array<() -> Void> = Array()
private let blocksQueue: NSOperationQueue()
func addBlockToArray(block: () -> Void) {
self.blocksArray.append(block)
}
func runBlocksInArray() {
for block in self.blocksArray {
let operation = NSBlockOperation(block: block)
self.blocksQueue.addOperation(operation)
}
self.blocksQueue.removeAll(keepCapacity: false)
}
}
Run Code Online (Sandbox Code Playgroud)
问题在于可以跨多个线程调用addBlockToArray.发生的事情是addBlockToArray在不同的线程中快速连续调用,并且只附加其中一个项目,因此在runBlocksInArray期间不会调用另一个项目.
我尝试过这样的东西,但似乎不起作用:
private let blocksDispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
func addBlockToArray(block: () -> Void) {
dispatch_async(blocksDispatchQueue) {
self.blocksArray.append(block)
}
}
Run Code Online (Sandbox Code Playgroud) arrays multithreading read-write grand-central-dispatch swift
这是可能的,因为Apple开源代码(libdispatch?)我对如何使用它感到困惑.这是一个具有任何应用程序可以使用的API的库,还是内置于Mac OS X中的操作系统功能?可以单独构建"for"Mac和iPhone(使用iOS 4)的应用程序吗?
我假设必须运行一个端口,以便gcc与Apple引入的新语义兼容.
我开始认为我的问题的答案是"不",但我仍然对此感到困惑和不确定.所以请确认.我已经了解了在使用多线程的Core Data时要小心.NSManagedObjectContext对象不得跨越线程边界.作为一个同时具有线程和核心数据的新手,我很高兴地发现GCD应该可以使其中的一些变得更容易.
或许,我想我会简单地创建一个专用的GCD调度队列来处理核心数据(如果需要,甚至可以有多个调度队列,每个队列都有自己的核心数据上下文).那会很简单.
但现在我意识到GCD调度队列的一大优势是它根据需要管理和使用多个线程.所以 - 如果我理解这一点 - 我交给同一个调度队列的任务最终可能会在不同的线程中运行,可能会将核心数据上下文从一个线程切换到另一个线程,并且出现问题.是对的吗?
我已经阅读了许多相关的问题和答案,例如Core Data和threads/Grand Central Dispatch,但我仍然有些困惑.使用GCD队列接受的问题答案确实确保在每个线程上创建新的上下文,但没有指出这样做的必要性.另一个答案是"您可以在名为com.yourcompany.appname.dataaccess的队列上执行所有CoreData工作",这似乎暗示只要Core Data工作仅限于一个GCD调度队列,那么一切正常.也许不是.
场景:
为了显示警报视图并保持UI响应,我使用了dispatch_queue:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_sync(dispatch_get_main_queue(), ^{
// Show the alert view
});
});
Run Code Online (Sandbox Code Playgroud)使用以下命令启动地址簿修改过程:
dispatch_async(modifyingAddressBookQueue, ^{});
Run Code Online (Sandbox Code Playgroud)现在,我想让用户随时取消该过程(当然在保存地址簿之前).因此,当他点击警报表中的取消按钮时,我想访问调度块,设置一些特定的BOOL来停止进程并还原地址簿.
问题是,你做不到!您无法访问该块并更改其中的任何变量,因为所有变量只复制一次.块执行时块内变量的任何变化都不会被块看到.
总结一下:如何使用UI事件停止正在进行的操作?
更新:
该过程的代码:
- (void) startFixingModification {
_fixContacts = YES;
__block BOOL cancelled = NO;
dispatch_queue_t modifyingAddressBookQueue;
modifyingAddressBookQueue = dispatch_queue_create(sModifyingAddressBookQueueIdentifier,
NULL);
dispatch_async(modifyingAddressBookQueue, ^{
for (NSMutableDictionary *contactDictionary in _contactArray) {
if (!cancelled) {
break;
}
i = i + 1;
BOOL didFixContact = [self fixNumberInContactDictionary:contactDictionary];
if (!didFixContact) {
_fixedNumbers = _fixedNumbers - 1;
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_sync(dispatch_get_main_queue(), ^{
[self …Run Code Online (Sandbox Code Playgroud) 到目前为止,我已经看到了这些问题的答案(1,2,3)建议使用GCD是dispatch_once这样的:
var token: dispatch_once_t = 0
func test() {
dispatch_once(&token) {
print("This is printed only on the first call to test()")
}
print("This is printed for each call to test()")
}
test()
Run Code Online (Sandbox Code Playgroud)
输出:
This is printed only on the first call to test()
This is printed for each call to test()
Run Code Online (Sandbox Code Playgroud)
但是等一下.token是一个变量,所以我可以很容易地做到这一点:
var token: dispatch_once_t = 0
func test() {
dispatch_once(&token) {
print("This is printed only on the first call …Run Code Online (Sandbox Code Playgroud) 在Swift中,我有时会使用这种模式.
DispatchQueue.global().async {
// do stuff in background, concurrent thread
DispatchQueue.main.sync {
// update UI
}
}
Run Code Online (Sandbox Code Playgroud)
这种模式的目的很明确.在全局线程中进行耗时的计算,因此UI未被锁定,并且在计算完成后更新主线程中的UI.
如果没有什么可计算的怎么办?我刚刚在我的项目中发现了一个逻辑
//A
DispatchQueue.main.sync {
// do something
}
Run Code Online (Sandbox Code Playgroud)
崩溃但是
// B
DispatchQueue.global().async {
DispatchQueue.main.sync {
// do something
}
}
Run Code Online (Sandbox Code Playgroud)
没有崩溃.
他们有什么不同?案例B是否与此不同?
// C
DispatchQueue.main.async {
// do something
}
Run Code Online (Sandbox Code Playgroud)
还有一个问题.我知道主线程是串行队列,但如果我多个运行多个代码块main.async,它就像并发队列一样.
DispatchQueue.main.async {
// do A
}
DispatchQueue.main.async {
// do B
}
Run Code Online (Sandbox Code Playgroud)
如果主线程实际上是一个串行队列,它们如何同时运行?如果它只是一个时间切片而不是它们与全局并发队列的不同而不是主线程可以更新UI?
这总是以1 5 2 4 3的顺序打印吗?
print("1")
DispatchQueue.main.async {
print("2")
DispatchQueue.main.async {
print(3)
}
print("4")
}
print("5")
Run Code Online (Sandbox Code Playgroud)
我觉得答案是否定的,但我无法解释,希望有人能澄清我的理解.谢谢!
asynchronous grand-central-dispatch ios dispatch-async swift
ios ×6
swift ×4
macos ×2
objective-c ×2
arrays ×1
asynchronous ×1
concurrency ×1
core-data ×1
iphone ×1
libdispatch ×1
portability ×1
read-write ×1
windows ×1
xcode ×1