标签: grand-central-dispatch

单元测试异步队列的模式,在完成时调用主队列

这与我之前提出的问题有关,但不同之处,我认为我会把它扔进一个新问题.我有一些代码在自定义队列上运行异步,然后在完成时在主线程上执行完成块.我想围绕这种方法编写单元测试.我的方法MyObject看起来像这样.

+ (void)doSomethingAsyncThenRunCompletionBlockOnMainQueue:(void (^)())completionBlock {

    dispatch_queue_t customQueue = dispatch_queue_create("com.myObject.myCustomQueue", 0);

    dispatch_async(customQueue, ^(void) {

        dispatch_queue_t currentQueue = dispatch_get_current_queue();
        dispatch_queue_t mainQueue = dispatch_get_main_queue();

        if (currentQueue == mainQueue) {
            NSLog(@"already on main thread");
            completionBlock();
        } else {
            dispatch_async(mainQueue, ^(void) {
                NSLog(@"NOT already on main thread");
                completionBlock();
        }); 
    }
});
Run Code Online (Sandbox Code Playgroud)

}

我投入了主队列测试以获得额外的安全性,但它总是能够击中dispatch_async.我的单元测试如下所示.

- (void)testDoSomething {

    dispatch_semaphore_t sema = dispatch_semaphore_create(0);

    void (^completionBlock)(void) = ^(void){        
        NSLog(@"Completion Block!");
        dispatch_semaphore_signal(sema);
    }; 

    [MyObject doSomethingAsyncThenRunCompletionBlockOnMainQueue:completionBlock];

    // Wait for async code to finish
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); …
Run Code Online (Sandbox Code Playgroud)

objective-c grand-central-dispatch sentestingkit

32
推荐指数
4
解决办法
1万
查看次数

C++ 11随机数生成器的线程安全性

在C++ 11中,有许多新的随机数生成器引擎和分发函数.它们是否安全?如果您在多个线程之间共享一个随机分布和引擎,它是否安全并且您是否仍会收到随机数?我正在寻找的场景是这样的,

void foo() {
    std::mt19937_64 engine(static_cast<uint64_t> (system_clock::to_time_t(system_clock::now())));
    std::uniform_real_distribution<double> zeroToOne(0.0, 1.0);
#pragma omp parallel for
    for (int i = 0; i < 1000; i++) {
        double a = zeroToOne(engine);
    }
}
Run Code Online (Sandbox Code Playgroud)

使用OpenMP或

void foo() {
    std::mt19937_64 engine(static_cast<uint64_t> (system_clock::to_time_t(system_clock::now())));
    std::uniform_real_distribution<double> zeroToOne(0.0, 1.0);
    dispatch_apply(1000, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(size_t i) {
        double a = zeroToOne(engine);
    });
}
Run Code Online (Sandbox Code Playgroud)

使用libdispatch.

c++ openmp thread-safety grand-central-dispatch c++11

32
推荐指数
2
解决办法
1万
查看次数

可以在单元测试中重置dispatch_once的状态,使它们再次运行

是否可以在单元测试tearDown中重置dispatch_once代码的状态?

我认为如果我们的单元测试可以从一个非常干净的状态运行会很好,但我们正在努力使用dispatch_once和一些使用dispatch进行的单例测试.

objective-c grand-central-dispatch

32
推荐指数
1
解决办法
1万
查看次数

Grand Central Dispatch中线程限制的解决方法?

使用Grand Central Dispatch,可以轻松地在非主线程上执行耗时的任务,避免阻止主要攻击并保持UI响应.只需dispatch_async在全局并发队列上使用并执行任务即可.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // code
});
Run Code Online (Sandbox Code Playgroud)

然而,听起来好得令人难以置信,因为这个通常有它们的缺点.在我们的iOS应用程序项目中使用了很多之后,最近我们发现它有64个线程限制.一旦我们达到限制,应用程序将冻结/挂起.通过暂停应用程序与Xcode,我们可以看到主线程由semaphore_wait_trap.

在网上搜索确认其他人也遇到了这个问题,但到目前为止还没有找到解决方案.

达到调度线程硬限制:64(同步操作中阻塞的调度线程太多)

另一个问题计算器证实了这一问题时使用发生dispatch_syncdispatch_barrier_async太.

问题:
由于Grand Central Dispatch有64个线程限制,有没有解决方法?

提前致谢!

objective-c grand-central-dispatch ios

32
推荐指数
1
解决办法
9311
查看次数

为什么我应该选择GCD而非NSOperation并阻止高级应用程序?

Apple的Grand Central Dispatch参考文献称:

"......如果你的应用程序需要在系统的Unix级别运行 - 例如,如果它需要操作文件描述符,Mach端口,信号或定时器.GCD不仅限于系统级应用程序,而是在你之前将它用于更高级别的应用程序时,您应该考虑Cocoa中提供的类似功能(通过NSOperation和块对象)是否更易于使用或更适合您的需求."

http://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html

对于高级应用程序,我实际上无法想到这种情况,其中GCD的使用是强制性的,并且可以/不应该使用NSOperation.

有什么想法吗?

concurrency objective-c grand-central-dispatch ios objective-c-blocks

31
推荐指数
2
解决办法
2万
查看次数

在单独的线程上调用我的方法有哪些不同的方法?

我有一些数据计算方法(让它是"myMethod:"),我想将调用移动到另一个线程,因为我不想阻止我的主UI功能.所以,开始研究如何在另一个线程上调用我的方法.据我所知,目前有很多不同的方法可以做到这一点.这是一个清单:

a)使用纯线程(自iOS 2.0起可用):

[NSThread detachNewThreadSelector:@selector(myMethod:) toTarget:self withObject:_myParamsArray];
Run Code Online (Sandbox Code Playgroud)

b)使用简单的快捷方式(从iOS 2.0开始提供).可从继承的NSObject获得,但该方法也属于NSThread类:

[self performSelectorInBackground:@selector(myMethod:) withObject:_myParamsArray];
Run Code Online (Sandbox Code Playgroud)

c)使用Grand Central Dispatch队列的新方法(自iOS 4.0起可用):

dispatch_async(dispatch_get_global_queue(0, 0),
  ^ {
      [self myMethod:_myParamsArray];
    });
Run Code Online (Sandbox Code Playgroud)

d)不知何故,使用一些类,如NSOperation,NSBlockOperation或NSOperationQueue,虽然不确定如何完成它(一些例子将被赞赏)

目前,我使用了案例"b",但对其利弊和其他相关建议充满好奇.

更新:e)还找到了执行类似线程的另一种方法 - 运行循环.以下是苹果文档的摘录:

运行循环是一个事件处理循环,用于计划工作并协调传入事件的接收.运行循环的目的是在有工作时保持线程忙,并在没有线程时让线程进入休眠状态.

恕我直言,或多或少你正在处理相同的任务 - 如何在单独的线程上调用你的方法进行异步操作.

更新2:已经有一些NSInvocationOperation和NSOperationQueue和恕我直言的经验,这是非常方便的.根据Apple文档,GCD和NSOperations是实现多线程的首选方式.此外,NSOperations从iOS 4.0开始在GCD上运行.简而言之,您实例化NSIvocationOperation(作为对您的方法的调用)然后实例化NSOperationQueue并将调用添加到队列.NSOperationQueue足够聪明,你可以实例化多个NSIvocationOperation对象(包装方法调用)并将它们实例化为NSOperationQueue.其余的都有保证.NSOperationQueue确定执行调用所需的并行线程数(NSInvocationOperation)并为您处理.它可以在线程A上执行第一次调用,然后在线程B上执行第二次调用,在线程C上执行第三次,在线程B上执行第三次调用,因此您不必担心这一点.但是如果你愿意,你可以告诉NSOperationQueue最大线程如何用于执行调用(例如1),但我没有必要这样做.默认情况下,所有任务都在主线程以外的位置执行,因此默认情况下操作队列是异步的.此外,如果要在严格队列中执行方法调用(每个包装在单独的NSInvocationOperation中),则可以添加依赖项,因此NSOperationQueue将保留方法调用顺序.这是一个例子:

// wrap your method call into NSInvocationOperation object
NSInvocationOperation *currentOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(yourMethodCall) object:nil];

// _sharedOperationQueue is a shared NSOperationQueue 
// get all executing operations from the queue and get the last operation
_lastOperation = [[_sharedOperationQueue operations] lastObject];

// check if _lastOperation is …
Run Code Online (Sandbox Code Playgroud)

concurrency multithreading objective-c grand-central-dispatch ios

31
推荐指数
1
解决办法
1万
查看次数

如何在GCD中停止DispatchWorkItem?

我目前正在玩Grand Central Dispatch并发现了一个名为的课程DispatchWorkItem.文档似乎有点不完整,所以我不确定以正确的方式使用它.我创建了以下代码段,并期待一些不同的东西.我希望在调用cancel它之后该项目将被取消.但由于某种原因,迭代仍在继续.我有什么想法我做错了吗?代码似乎对我来说很好.

@IBAction func testDispatchItems() {
    let queue = DispatchQueue.global(attributes:.qosUserInitiated)
    let item = DispatchWorkItem { [weak self] in
        for i in 0...10000000 {
            print(i)
            self?.heavyWork()
        }
    }

    queue.async(execute: item)
    queue.after(walltime: .now() + 2) {
        item.cancel()
    }
}
Run Code Online (Sandbox Code Playgroud)

grand-central-dispatch cancellation swift dispatchworkitem

31
推荐指数
1
解决办法
1万
查看次数

暂停GCD查询问题

我无法暂停gcd查询.以下是一些演示此问题的代码:

static dispatch_queue_t q=nil;

static void test(int a){
    if(q){
        dispatch_suspend(q);
        dispatch_release(q);
        q=nil;
    }
    q=dispatch_get_global_queue(0,0);
    dispatch_async(q,^ {
        while(1){NSLog(@"query %d",a);sleep(2);}
    });

}

int main(int argc, const char* argv[]){
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    test(1);

    //blah blah blah

    test(2);

    while(1){}
    [pool release];
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试做的是在第二次调用函数测试时暂停,释放和重新初始化查询q,但显然我的代码是错误的,并且查询q的两个实例都继续运行.

非常感谢您的帮助,谢谢.

objective-c grand-central-dispatch

30
推荐指数
2
解决办法
3万
查看次数

Grand Central Dispatch vs NSThreads?

我搜索了各种来源,但并不真正理解使用NSThreads和GCD 之间的区别.我是OS X平台的新手,所以我可能完全误解了这个.

从我在线阅读的内容来看,GCD似乎与基本线程(POSIX NSThreads等)完全相同,同时添加了更多技术术语("块").它似乎只是使基本的线程创建系统(创建线程,运行函数)过于复杂.

GCD究竟是什么?为什么它会优于传统的线程?应该何时使用传统线程而不是GCD?最后是否有GCD奇怪语法的原因?("块"而不是简单地调用函数).

我在Mac OS X 10.6.8 Snow Leopard上,我不是为iOS编程 - 我正在为Mac编程.我在Cocoa中使用Xcode 3.6.8,创建了一个GUI应用程序.

macos cocoa multithreading objective-c grand-central-dispatch

30
推荐指数
3
解决办法
2万
查看次数

NSThread vs. NSOperationQueue vs. ??? 在iPhone上

目前我正在使用NSThread另一个线程缓存图像.

[NSThread detachNewThreadSelector:@selector(cacheImage:) toTarget:self withObject:image];
Run Code Online (Sandbox Code Playgroud)

交替:

[self performSelectorInBackground:@selector(cacheImage:) withObject:image];
Run Code Online (Sandbox Code Playgroud)

或者,我可以使用 NSOperationQueue

NSInvocationOperation *invOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(cacheImage:) object:image];
NSOperationQueue *opQueue = [[NSOperationQueue alloc] init];
[opQueue addOperation:invOperation];
Run Code Online (Sandbox Code Playgroud)

有没有理由改变NSThread?GCD是iPhone上发布的第四个选项,但除非有显着的性能提升,否则我宁愿坚持使用适用于大多数平台的方法.


根据@ Jon-Eric的建议,我选择了NSOperationQueue/ NSOperation子类解决方案.它工作得很好.该NSOperation班是足够灵活,你可以调用,块或定制子类使用它,这取决于你的需求.无论您如何创建自己,NSOperation都可以在准备运行时将其放入操作队列中.如果需要,这些操作可以作为您放入队列的对象,也可以作为独立的异步方法运行.由于您可以轻松地同步运行自定义操作方法,因此测试非常简单.

我在一些项目中使用了相同的技术,因为我问了这个问题,我对它保持我的代码和我的测试干净,有条理和快乐异步的方式感到高兴.

A +++++++++++++++++++++++++

iphone nsthread nsoperationqueue grand-central-dispatch

29
推荐指数
2
解决办法
1万
查看次数