GCD:如何从两个线程写入和读取变量

时间:2012-06-17 11:26:28

标签: iphone objective-c multithreading ipad grand-central-dispatch

这听起来可能是一个新手问题,我是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);
}

3 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:1)

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

创建互斥锁并初始化

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

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

pthread_mutex_lock(self_mutex);
{
    ** Code here
}
pthread_mutex_unlock(self_mutex);

答案 2 :(得分:0)

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