1

无论如何,这听起来可能是一个新手问题我是 GCD 的新手,

我正在创建并运行以下两个线程。第一个将数据放入 ivar mMutableArray,第二个从中读取数据。我如何锁定和解锁线程以避免崩溃并保持代码线程安全?

// Thread for writing data into mutable array 
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
if (timer) {
    dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * interval), interval * NSEC_PER_SEC, leeway);
    dispatch_source_set_event_handler(timer, ^{
        ...
        // Put data into ivar
        [mMutableArray addObject:someObject];
        ...
    });
    dispatch_resume(timer);
}

// Thread for reading from mutable array
dispatch_source_t timer1 = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
if (timer1) {
    dispatch_source_set_timer(timer1, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * interval), interval * NSEC_PER_SEC, leeway);
    dispatch_source_set_event_handler(timer1, ^{
        ...
        if (mMutableArray) {
            // Read data from ivar
            SomeObject* someobject = [mMutableArray lastObject];
        }
        ...
    });
    dispatch_resume(timer1);
}
4

3 回答 3

6

你用错了,通过锁定对变量的访问,你只是失去了 GCD 的任何好处。创建一个与您要修改的变量相关联的串行队列(在本例中为可变数组)。然后使用该队列对其进行写入和读取,这将以保证的串行顺序发生并且具有最小的锁定开销。您可以在http://www.fieryrobot.com/blog/2010/09/01/synchronization-using-grand-central-dispatch/上的“异步设置器”中阅读有关它的更多信息。只要您通过其关联的调度队列访问共享变量,您就不会遇到并发问题。

于 2012-06-17T13:20:00.673 回答
1

我在我的项目中使用了互斥锁,我对它目前的工作方式非常满意。

创建互斥体并初始化它

pthread_mutex_t *mutexLock;
pthread_mutex_init(&_mutex, NULL);

然后将锁放在您的代码周围,一旦第二个线程尝试获取锁,它将等到第一个线程再次释放锁。请注意,您仍然可能想检查第一个线程是否实际上是写入它的线程。

pthread_mutex_lock(self_mutex);
{
    ** Code here
}
pthread_mutex_unlock(self_mutex);
于 2012-06-17T12:42:37.683 回答
0

您仍然可以在 GCD 的关键部分上使用 @synchronized

于 2012-06-17T11:31:54.237 回答