您的位置:首页 > 移动开发 > IOS开发

iOS 生产者消费者

2016-07-18 13:41 435 查看
在编码中,有时会遇到一个模块产生数据,另外一个模块处理数据的情况,不论是为了模块间的结偶或是并发处理还是忙闲不均,我们都会在产生和处理数据的模块之间放置缓存区,作为生产和处理数据的仓库。以上的模型就是生产者消费者模型。

为了简化上述模型,生产者和消费者只用一个线程替代,缓存区用数组表示。

我们知道,多个线程数据进行读写,要对这个共享数据进行读写保护,也就是线程的同步。在ios中,我们可以通过加锁(NSlock)、同步块@synchronized及NSCondition等对共享资源进行保护。

1、//消费者(NSLock)

- (void)createSaller {

    dispatch_queue_t queue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0);

    dispatch_async(queue, ^{

        while (1) {

            [_lock lock];

            if (_array.count) {

                [_array
removeObjectAtIndex:0];

                NSLog(@"sall a good:%lu", (unsigned
long)_array.count);

            }

   [_lock unlock];

        }

    });

}

//生产者(NSLock)

- (void)createProductor {

    dispatch_queue_t queue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0);

    dispatch_async(queue, ^{

        while (1) {

            [_lock
lock];

            if (_array.count ==
0) {

                [_array
addObject:@""];

                NSLog(@"create a good:%lu", (unsigned
long)_array.count);

            }

           [_lock unlock];

        }

    });

}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2、同步块@synchronized,只需要把lock和unlock间的代码放大同步块之间即可

    @synchronized(self) {

          if (_array.count) {

               [_array
removeObjectAtIndex:0];

                NSLog(@"sall a good:%lu", (unsigned
long)_array.count);

         }

  }

3、NSCondition在同步在的应用跟lock是一样的

      [_condition
lock];

         if (_array.count) {

                [_array
removeObjectAtIndex:0];

                 NSLog(@"sall a good:%lu", (unsigned
long)_array.count);

            }

       }

      [_condition
unlock];

NSlock和NScondition的区别:

NSCondition除了当做锁之外,还能处理线程之间的调度。

我们知道,线程的调度是操作系统的事,对我们是透明的,但是某些时候我们想自己控制线程的调度,那NSCondition就派上用场了。

比如上面的生产者消费者代码:缓存区(_array)是空的时候,消费者线程就休眠,生产者生产出产品之后,唤醒消费者线程消费产品。

这时NScondition就派上用场了:

- (void)createSaller {

    dispatch_queue_t queue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0);

    dispatch_async(queue, ^{

        while (1) {

            [_condition
lock];

            if (_array.count) {

                [_array
removeObjectAtIndex:0];

                NSLog(@"sall a good:%lu", (unsigned
long)_array.count);

            }

            else {

                [_condition
wait];

            }

            [_condition unlock];

        }

    });

}

- (void)createProductor {

    dispatch_queue_t queue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0);

    dispatch_async(queue, ^{

        while (1) {

            [_condition
lock];

            if (_array.count ==
0) {

                [_array
addObject:@""];

                NSLog(@"create a good:%lu", (unsigned
long)_array.count);

            }

            else {

                [_condition
signal];

            }

            [_condition unlock];

        }

    });

}

体外:

NSCondition可以实现NSlock的所有功能,那为什么还需要NSlock,其实这个跟BOOL和NSINteger的道理是一样的,NSINteger完全可以替代BOOL的功能,但是BOOL在某些时候看起来更接近人的表达或者说是思维。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: