Dispatch Semaphore

A
dispatch semaphore(
信号量) is
useful if you need a concurrency control for a small
portion(
部分) of the source code that has
smaller granularity(
颗粒度) than
a serial dispatch
queue or dispatch_barrier_async function.

If data are updated concurrently, inconsistent(不一致的) data might
occur or the application might crash. You can avoid that by using a serial
dispatch queue or the dispatch_barrier_async function. But sometimes concurrency
control has to be done in smaller granularity.

(其实iOS的dispatch
semaphore和Windows系统的Semaphore的作用是一样的,都是用来作线程同步或者说资源的互斥访问的。当然在Windows系统下,除了Semaphore之外,CriticalSection、Event、Mutex也可以完成此功能。)

Let’s see an example to show how to add all the data to an
NSMutableArray when the order is unimportant.





1

2

3

4

5

6

7

8

9

10

dispatch_queue_t queue=

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

NSMutableArray*array=[[NSMutableArrayalloc] init];

for(inti=0;i<100000;++i){

dispatch_async(queue,^{

[array
addObject:[NSNumber numberWithInt:i]];

});

}

But, because the NSMutableArray class
doesn’t support multithreading, when the object is updated from many threads, it
will be corrupted(
损坏). The
application probably crashes because of a memory-related problem. This is a race
condition(竞态[争]条件). We can use a dispatch semaphore in this case.

A dispatch semaphore is a semaphore with a counter. When
the counter is zero, the execution waits. When the counter is more than zero, it
keeps going after it decrements the counter.

The dispatch_semaphore_create function
creats a dispatch
semaphore.
(相当于Windows系统的CreateSemaphore)





1

dispatch_semaphore_t semaphore=dispatch_semaphore_create(1);

The argument is an initial value of the counter. As its name includes
“create”, you have to release it with the dispatch_release function. You can
have ownership by calling the dispatch_retain function as well.





1

dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);

A dispatch_semaphore_wait function waits until
the counter of the dispatch semaphore becomes one and more.
 When
the counter is one and more, or the counter becomes one and more while it is
waiting, it decreases the counter and returns from the dispatch_semaphore_wait
function. The second argument specifies how long it waits in dispatch_time_t
type. In this example, it waits forever. The return value is the same as that of
the dispatch_group_wait function.





1

2

3

4

5

6

7

8

9

10

11

12

13

dispatch_time_t time=dispatch_time(DISPATCH_TIME_NOW,1ull*NSEC_PER_SEC);

longresult=dispatch_semaphore_wait(semaphore,time);

if(result==0){

//The counter of
the dispatch semaphore was more than one.

//Or it became
one and more before the specified timeout.

//The counter is
automatically decreased by one.

//Here, you can
execute a task that needs a concurrency control.

}else{

//Because the
counter of the dispatch semaphore was zero,

//it has waited
until the specified timeout.

}

When a dispatch_semaphore_wait function returns zero, a task that needs a
concurrency control can be executed safely. After finish the task,
you have to call
thedispatch_semaphore_signal
(相当于Windows系统的ReleaseSemaphore) function
to increase the counter of the dispatch semaphore by one.






1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

dispatch_queue_t queue=

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

//Set the initial
value 1 for the counter of the dispatch semaphore

//to
assure that only one thread will access the object of

//NSMutableArray
class at the same time.

dispatch_semaphore_t semaphore=dispatch_semaphore_create(1);

NSMutableArray*array=[[NSMutableArrayalloc] init];

for(inti=0;i<100000;++i){

dispatch_async(queue,^{

dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);

//The counter of the dispatch semaphore is always zero
here.

//Because only one thread can access the object of the
NSMutableArray class

//at the same time, you can update the object
safely.

[array
addObject:[NSNumber numberWithInt:i]];

//you have to call the dispatch_semaphore_signal
function

//to increase the counter of the dispatch
semaphore.

//If some threads are waiting for the
dispatch_semasphore

//the first thread will be started.

dispatch_semaphore_signal(semaphore);

});

}

//Originally,
because the dispatch semaphore isn’t needed any more,

//you have to release the dispatch semaphore.

//dispatch_release(semaphore);

整理自《Multithreading and Memory Management for iOS and OS X》

时间: 2024-10-03 13:40:03

Dispatch Semaphore的相关文章

dispatch

GCD提供了并管理着若干FIFO队列(queues),可以通过block的形式向这些FIFO序列提交任务.GCD同时维护着一个线程池,所有的任务在线程池的线程运行. 系统提供的队列 main queue 系统在启动后会创建一个特殊的队列,叫做主队列(main queue).主队列中的任务在主线程中顺序执行.(也就是说主线程上的不一定是主队列) Attempting to synchronously execute a work item on the main queue results in

详解IOS开发应用之并发Dispatch Queues (2011)

详解IOS开发应用之并发Dispatch Queues是本文哟啊介绍的内容,我们几乎可以调度队列去完成所有用线程来完成的任务.调度队列相对于线程代码更简单,易于使用,更高效.下面讲主要简述调度队列,在应用中如何使用调度队列去执行任务. 1.关于调度队列 所有的调度队列都是先进先出队列,因此,队列中的任务的开始的顺序和添加到队列中的顺序相同.GCD自动的为我们提供了一些调度队列,我们也可以创建新的用于具体的目的. 下面列出几种可用的调度队列类型以及如何使用. (1)serial queues(串行

dispatch queues GCD

我们几乎可以调度队列去完成所有用线程来完成的任务.调度队列相对于线程代码更简单,易于使用,更高效. 下面讲主要简述调度队列,在应用中如何使用调度队列去执行任务. 1.关于调度队列 所有的调度队列都是先进先出队列,因此,队列中的任务的开始的顺序和添加到队列中的顺序相同.GCD自动的为我们提供了一些调度队列,我们也可以创建新的用于具体的目的. 下面列出几种可用的调度队列类型以及如何使用. (1)serial queues(串行队列)又称私有调度队列(private),一般用在对特定资源的同步访问上.

Grand Central Dispatch (GCD) 转

GCD是异步执行任务的技术之一. GCD使用很简洁的记述方法,实现了极为复杂繁琐的多线程编程. dispatch_async(queue, ^{ //长时间处理 //例如AR用动画识别 //例如数据库访问 //长时间处理结束,主线程使用该处理结果 dispatch_async( dispatch_get_main_queue(), ^{ //只在主线程可以执行的处理 //例如用户界面更新 }); }); 在NSObject中,提供了两个实例方法来实现简单的多线程技术:performSelecto

Dispatch Queues调度队列

前言-死锁案例 // 在主线程中执行 dispatch_queue_t queueMain = dispatch_get_main_queue(); dispatch_sync(queueMain, ^{ NSLog(@"+++++++"); }); NSLog(@"hahahaha"); 案例分析:运行结果是程序阻塞在dispatch_sync()处.由于main线程执行到dispatch_sync()处,线程处于等待状态.将block任务块添加到主串行队列最后,

转----详解IOS开发应用之并发Dispatch Queues

详解IOS开发应用之并发Dispatch Queues是本文要介绍的内容,我们几乎可以调度队列去完成所有用线程来完成的任务.调度队列相对于线程代码更简单,易于使用,更高效.下面讲主要简述调度队列,在应用中如何使用调度队列去执行任务. 1.关于调度队列 所有的调度队列都是先进先出队列,因此,队列中的任务的开始的顺序和添加到队列中的顺序相同.GCD自动的为我们提供了一些调度队列,我们也可以创建新的用于具体的目的. 下面列出几种可用的调度队列类型以及如何使用. (1)serial queues(串行队

Cocoa多线程编程之block与semaphore(信号量)

首先大家要了解 dispatch_queue 的运作机制及线程同步 我们可以将许多 blocks 用 dispatch_async 函数提交到 dispatch_queue ,如果类型是DISPATCH_QUEUE_SERIAL (串行),那么这些 block 是按照 FIFO (先入先出)的规则调度的,也就是说,先加入的先执行,后加入的一定后执行,但在如果类型是DISPATCH_QUEUE_CONCURRENT(并行),那么某一时刻就可能有多个 block 同时在执行. 这个时候,如果两个 b

Swift - 多线程实现方式 - Grand Central Dispatch(GCD)

1,Swift继续使用Object-C原有的一套线程,包括三种多线程编程技术:(1)Thread(2)Cocoa Operation(Operation和OperationQueue)(3)Grand Central Dispath(GCD) 2,本文着重介绍Grand Central Dispath(GCD) GCD是Apple开发的一个多核编程的解决方法,基本概念就是dispatch queue(调度队列),queue是一个对象,它可以接受任务,并将任务以先到先执行的顺序来执行.dispat

iOS多线程系列(三)----Dispatch Queues

转载自:http://blog.sina.com.cn/s/blog_6dce99b10101atsu.html,尊重原创! 详解IOS开发应用之并发Dispatch Queues是本文要介绍的内容,我们几乎可以调度队列去完成所有用线程来完成的任务.调度队列相对于线程代码更简单,易于使用,更高效.下面讲主要简述调度队列,在应用中如何使用调度队列去执行任务. 1.关于调度队列 所有的调度队列都是先进先出队列,因此,队列中的任务的开始的顺序和添加到队列中的顺序相同.GCD自动的为我们提供了一些调度队