您的位置:首页 > 理论基础 > 计算机网络

第01天多线程网络:(13):GCD的基本使用

2017-04-17 00:00 316 查看
GCD的基本使用

同步和异步主要影响 : 能不能开启新的线程
同步 : 只能在当前线程中执行任务, 不具备开启新线程的能力
异步 : 可以在新的线程中执行任务, 具备开启新线程的能力

并发和串行主要影响 : 任务的执行方式
并发 :  可以让多个任务并发(同时)执行
串行 :  一个任务执行完毕后,再执行下一个任务


四个组合
一、异步函数 + 并发队列 : dispatch_async + DISPATCH_QUEUE_CONCURRENT
二、异步函数 + 串行队列 : dispatch_async + DISPATCH_QUEUE_SERIAL
三、同步函数 + 并发队列 : dispatch_sync + DISPATCH_QUEUE_CONCURRENT
四、同步函数 + 串行队列 : dispatch_sync + DISPATCH_QUEUE_SERIAL

#####一、异步函数 + 并发队列___(异步)
dispatch_async
__(并发)
DISPATCH_QUEUE_CONCURRENT


执行的操作:会开启
多条
线程,队列中任务是
并发
执行的(
一起执行
)

#pragma mark 一、异步函数 + 并发队列 :
// 会开启多条线程,队列中任务是并发执行的(一起执行)
- (void)async_Concurrent
{
// 1.创建队列 (并发、串行队列)
#pragma 1.创建队列 (并发、串行队列)      dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);

/**
dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);
Description
Creates a new dispatch queue to which blocks can be submitted.
Blocks submitted to a serial queue are executed one at a time in FIFO order. Note, however, that blocks submitted to independent queues may be executed concurrently with respect to each other. Blocks submitted to a concurrent queue are dequeued in FIFO order but may run concurrently if resources are available to do so.
If your app isn’t using ARC, you should call dispatch_release on a dispatch queue when it’s no longer needed. Any pending blocks submitted to a queue hold a reference to that queue, so the queue is not deallocated until all pending blocks have completed.
Parameters
label
A string label to attach to the queue to uniquely identify it in debugging tools such as Instruments, sample, stackshots, and crash reports. Because applications, libraries, and frameworks can all create their own dispatch queues, a reverse-DNS naming style (com.example.myqueue) is recommended. This parameter is optional and can be NULL.
attr
In OS X v10.7 and later or iOS 4.3 and later, specify DISPATCH_QUEUE_SERIAL (or NULL) to create a serial queue or specify DISPATCH_QUEUE_CONCURRENT to create a concurrent queue. In earlier versions, you must specify NULL for this parameter.
Returns
The newly created dispatch queue.
Availability	iOS (4.0 and later), macOS (10.6 and later), tvOS (4.0 and later), watchOS (2.0 and later)

*/

/**
参数1 : C语言的字符串,标签 <#const char * _Nullable label#>
参数2 : 队列的类型(并发、串行) <#dispatch_queue_attr_t  _Nullable attr#>
返回值 : dispatch_queue_t
#define DISPATCH_QUEUE_SERIAL NULL 串行队列
#define DISPATCH_QUEUE_CONCURRENT  并发队列

*/
dispatch_queue_t queue = dispatch_queue_create("com.lyh.download", DISPATCH_QUEUE_CONCURRENT);

#pragma 2.1封装任务(同步函数、异步函数) 2.2 把任务添加到队列中      void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

/**
void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
Description
Submits a block for asynchronous execution on a dispatch queue and returns immediately.
This function is the fundamental mechanism for submitting blocks to a dispatch queue. Calls to this function always return immediately after the block has been submitted and never wait for the block to be invoked. The target queue determines whether the block is invoked serially or concurrently with respect to other blocks submitted to that same queue. Independent serial queues are processed concurrently with respect to each other.
Parameters
queue
The queue on which to submit the block. The queue is retained by the system until the block has run to completion. This parameter cannot be NULL.
block
The block to submit to the target dispatch queue. This function performs Block_copy and Block_release on behalf of callers. This parameter cannot be NULL.
Availability	iOS (4.0 and later), macOS (10.6 and later), tvOS (4.0 and later), watchOS (2.0 and later)
*/

/*
参数1 : 队列 <#dispatch_queue_t  _Nonnull queue#>
参数2 : block(要执行的任务) <#^(void)block#>
*/
dispatch_async(queue, ^{
NSLog(@"-- download1 -- %@",[NSThread currentThread]);
});

dispatch_async(queue, ^{
NSLog(@"-- download2 -- %@",[NSThread currentThread]);
});

dispatch_async(queue, ^{
NSLog(@"-- download3 -- %@",[NSThread currentThread]);
});

/*
// 并发执行 无顺序

2017-04-20 17:16:35.682 13.GCD的基本使用[2420:409931] -- download1 -- <NSThread: 0x618000069040>{number = 3, name = (null)}
2017-04-20 17:16:35.682 13.GCD的基本使用[2420:409935] -- download3 -- <NSThread: 0x61000006c6c0>{number = 5, name = (null)}
2017-04-20 17:16:35.682 13.GCD的基本使用[2420:409934] -- download2 -- <NSThread: 0x600000066880>{number = 4, name = (null)}
*/
}

#####二、异步函数 + 串行队列___(异步)
dispatch_async
__(串行)
DISPATCH_QUEUE_SERIAL

执行的操作:开
一条
线程,队列中的任务是
串行
执行的(
一个执行完毕,再执行下一个
)

#pragma mark 二、异步函数 + 串行队列 :
// 开一条线程,队列中的任务是串行执行的(一个执行完毕,再执行下一个)
- (void)async_Serial
{
// 1. 创建队列
// #define DISPATCH_QUEUE_SERIAL NULL 串行队列
dispatch_queue_t queue = dispatch_queue_create("download", DISPATCH_QUEUE_SERIAL);

// 2.封装任务、把任务添加到队列中
dispatch_async(queue, ^{
NSLog(@"-- download1 -- %@",[NSThread currentThread]);
});

dispatch_async(queue, ^{
NSLog(@"-- download2 -- %@",[NSThread currentThread]);
});

dispatch_async(queue, ^{
NSLog(@"-- download3 -- %@",[NSThread currentThread]);
});

/*
串行执行 有顺序
2017-04-20 17:23:56.041 13.GCD的基本使用[2443:421112] -- download1 -- <NSThread: 0x618000077080>{number = 3, name = (null)}
2017-04-20 17:23:56.042 13.GCD的基本使用[2443:421112] -- download2 -- <NSThread: 0x618000077080>{number = 3, name = (null)}
2017-04-20 17:23:56.042 13.GCD的基本使用[2443:421112] -- download3 -- <NSThread: 0x618000077080>{number = 3, name = (null)}
*/
}

#####三、同步函数 + 并发队列___(同步)
dispatch_sync
__(并发)
DISPATCH_QUEUE_CONCURRENT

执行的操作:
不会
开子线程,任务是
串行
执行的

- (void)sync_Concurrent
{
// 1.创建一个并发队列
dispatch_queue_t queue = dispatch_queue_create("com.lyh.download", DISPATCH_QUEUE_CONCURRENT);

// 2.封装任务、把任务添加到队列中
dispatch_sync(queue, ^{
NSLog(@"-- download1 -- %@",[NSThread currentThread]);
});

dispatch_sync(queue, ^{
NSLog(@"-- download2 -- %@",[NSThread currentThread]);
});

dispatch_sync(queue, ^{
NSLog(@"-- download3 -- %@",[NSThread currentThread]);
});
}

#####四、同步函数 + 串发队列___(同步)
dispatch_sync
__(串发)
DISPATCH_QUEUE_SERIAL

执行的操作:
不会
开子线程,任务是
串行
执行的

- (void)sync_Serial
{
// 1.创建一个并发队列
dispatch_queue_t queue = dispatch_queue_create("com.lyh.download", DISPATCH_QUEUE_SERIAL);

// 2.封装任务、把任务添加到队列中
dispatch_sync(queue, ^{
NSLog(@"-- download1 -- %@",[NSThread currentThread]);
});

dispatch_sync(queue, ^{
NSLog(@"-- download2 -- %@",[NSThread currentThread]);
});

dispatch_sync(queue, ^{
NSLog(@"-- download3 -- %@",[NSThread currentThread]);
});
}

#####五、获取全局并发队列
dispatch_queue_t dispatch_get_global_queue(long identifier, unsigned long flags);


#pragma mark 获取全局并发队列      dispatch_queue_t dispatch_get_global_queue(long identifier, unsigned long flags);
// 获取全局并发队列
/*
dispatch_queue_t dispatch_get_global_queue(long identifier, unsigned long flags);
Description
Returns a system-defined global concurrent queue with the specified quality of service class.
This function returns a queue suitable for executing tasks with the specified quality-of-service level. Calls to the dispatch_suspend, dispatch_resume, and dispatch_set_context functions have no effect on the returned queues.
Tasks submitted to the returned queue are scheduled concurrently with respect to one another.
Parameters
identifier
The quality of service you want to give to tasks executed using this queue. Quality-of-service helps determine the priority given to tasks executed by the queue. You may specify the values QOS_CLASS_USER_INTERACTIVE, QOS_CLASS_USER_INITIATED, QOS_CLASS_UTILITY, or QOS_CLASS_BACKGROUND. Queues that handle user-interactive or user-initiated tasks have a higher priority than tasks meant to run in the background.
In OS X 10.9 or earlier, you can specify one of the dispatch queue priority values, which are found in Dispatch Queue Priorities. These values map to an appropriate quality-of-service class.
flags
Flags that are reserved for future use. Always specify 0 for this parameter.
Returns
The requested global concurrent queue.
Availability	iOS (4.0 and later), macOS (10.6 and later), tvOS (4.0 and later), watchOS (2.0 and later)
*/

/*
参数1 : 优先级 <#long identifier#>
参数2 : 给未来使用的(传递0) <#unsigned long flags#>

优先级
#define DISPATCH_QUEUE_PRIORITY_HIGH        // 最高
#define DISPATCH_QUEUE_PRIORITY_DEFAULT     // 默认
#define DISPATCH_QUEUE_PRIORITY_LOW         // 低优先级
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND  // 最低
*/
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);

#####六、使用GCD的误区

创建多少个任务是不是就创建了多少个线程?
答:不是的 可能创建6个任务。系统只用2条线程去解决任务。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息