<span id="Label3"></p><p><p>This paper is a collation of knowledge points in multi-threading in previous Studies.</p></p><p><p>Queues in multiple threads are: <strong>serial queue, concurrent queue, Global queue, home row</strong> .</p></p><p><p>The methods performed are <strong>synchronous execution and asynchronous execution</strong> . So what are the considerations for the 221 combination?</p></p><p><p>If you don't see this article in the Dong Platinum blog park, Please click here to view the original</p></p><p><p>Refers to multi-threading, that is, four kinds, pthread,nsthread,gcd,nsoperation</p></p><p><p>where Phtread is Cross-platform. GCD and Nsoperation are common, and the latter is based on the Former.</p></p><p><p>But the difference: the core concept of GCD is to add a task to the queue, specify the method that the task executes, and then execute it. The nsoperation is to add an operation directly to the Queue.</p></p><p><p>For the whole structure to be clearer, I used the GCD to do this sort of combination experiment. The experiment is to judge the result by the sequence of printing in the loop and the main thread, and then summarize it.</p></p>1. Serial queue, Synchronous execution <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="gutter">12345678910</td> <td class="code"><code class="objc plain"><code class="objc plain">dispatch_queue_t q = dispatch_queue_create(</code></code><code class="objc string"><code class="objc string">"dantesx"</code></code><code class="objc plain"><code class="objc plain">, </code></code><code class="objc keyword"><code class="objc keyword">NULL</code></code><code class="objc plain"><code class="objc plain">);</code></code> <code class="objc comments"><code class="objc comments">// 执行任务</code></code><code class="objc keyword"><code class="objc keyword">for</code></code><code class="objc plain"><code class="objc plain">(</code></code><code class="objc datatypes"><code class="objc datatypes">int</code></code><code class="objc plain"><code class="objc plain">i = 0; i<10; i++) {</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">dispatch_sync(q, ^{</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"%@ %d"</code></code><code class="objc plain"><code class="objc plain">, [</code></code><code class="objc keyword"><code class="objc keyword">NSThread</code></code><code class="objc plain"><code class="objc plain">currentThread], i);</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">});</code></code><code class="objc plain"><code class="objc plain">}</code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"董铂然 come here"</code></code><code class="objc plain"><code class="objc plain">);</code></code></td> </tr> </tbody> </table><p><p>Operating Effect:</p></p><p><p></p></p><p><p>Execution results can be clearly seen all in the main thread execution, and is executed in sequence, after the end of the loop to print the main thread Output.</p></p>2. Serial queue, Asynchronous execution <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="gutter">123456789</td> <td class="code"><code class="objc plain"><code class="objc plain">dispatch_queue_t q = dispatch_queue_create(</code></code><code class="objc string"><code class="objc string">"dantesx"</code></code><code class="objc plain"><code class="objc plain">, </code></code><code class="objc keyword"><code class="objc keyword">NULL</code></code><code class="objc plain"><code class="objc plain">);</code></code><code class="objc keyword"><code class="objc keyword">for</code></code><code class="objc plain"><code class="objc plain">(</code></code><code class="objc datatypes"><code class="objc datatypes">int</code></code> <code class="objc plain"><code class="objc plain">i = 0; i<10; i++) {</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">dispatch_async(q, ^{</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"%@ %d"</code></code><code class="objc plain"><code class="objc plain">, [</code></code><code class="objc keyword"><code class="objc keyword">NSThread</code></code><code class="objc plain"><code class="objc plain">currentThread], i);</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">});</code></code><code class="objc plain"><code class="objc plain">}</code></code><code class="objc comments"><code class="objc comments">// [NSThread sleepForTimeInterval:0.001];</code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"董铂然 come here"</code></code><code class="objc plain"><code class="objc plain">);</code></code></td> </tr> </tbody> </table><p><p>Run results</p></p><p><p></p></p><p><p>The result shows that the system has 1 asynchronous threads open, so all thread 2 executes and is executed sequentially. The main thread is printed in the top, but this sequence is not sure, if you sleep for 0.001 seconds, the main thread of the printing will be mixed in the Middle.</p></p>3. Concurrent queues, Asynchronous execution <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="gutter">1234567891011</td> <td class="code"><code class="objc comments"><code class="objc comments">// 1. 队列</code></code><code class="objc plain"><code class="objc plain">dispatch_queue_t q = dispatch_queue_create(</code></code><code class="objc string"><code class="objc string">"dantesx"</code></code><code class="objc plain"><code class="objc plain">, DISPATCH_QUEUE_CONCURRENT);</code></code><code class="objc comments"><code class="objc comments">// 2. 异步执行</code></code><code class="objc keyword"><code class="objc keyword">for</code></code><code class="objc plain"><code class="objc plain">(</code></code><code class="objc datatypes"><code class="objc datatypes">int</code></code><code class="objc plain"><code class="objc plain">i = 0; i<10; i++) {</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">dispatch_async(q, ^{</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"%@ %d"</code></code><code class="objc plain"><code class="objc plain">, [</code></code><code class="objc keyword"><code class="objc keyword">NSThread</code></code><code class="objc plain"><code class="objc plain">currentThread], i);</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">});</code></code><code class="objc plain"><code class="objc plain">}</code></code><code class="objc comments"><code class="objc comments">// [NSThread sleepForTimeInterval:2.0];</code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"董铂然 come here"</code></code><code class="objc plain"><code class="objc plain">);</code></code></td> </tr> </tbody> </table><p><p>Run results</p></p><p><p></p></p><p><p>The results show that the main thread of the printing is still mixed in the middle of the uncertainty, because the asynchronous thread is who does not wait for who. The system opens multiple threads, and the order of execution is Chaotic.</p></p><p><p></p></p>4. Concurrent queue, Synchronous execution <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="gutter">1234567891011</td> <td class="code"><code class="objc comments"><code class="objc comments">// 1. 队列</code></code><code class="objc plain"><code class="objc plain">dispatch_queue_t q = dispatch_queue_create(</code></code><code class="objc string"><code class="objc string">"dantesx"</code></code><code class="objc plain"><code class="objc plain">, DISPATCH_QUEUE_CONCURRENT);</code></code><code class="objc comments"><code class="objc comments">// 2. 同步执行</code></code><code class="objc keyword"><code class="objc keyword">for</code></code><code class="objc plain"><code class="objc plain">(</code></code><code class="objc datatypes"><code class="objc datatypes">int</code></code><code class="objc plain"><code class="objc plain">i = 0; i<10; i++) {</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">dispatch_sync(q, ^{</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"%@ %d"</code></code><code class="objc plain"><code class="objc plain">, [</code></code><code class="objc keyword"><code class="objc keyword">NSThread</code></code><code class="objc plain"><code class="objc plain">currentThread], i);</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">});</code></code><code class="objc plain"><code class="objc plain">}</code></code><code class="objc comments"><code class="objc comments">// [NSThread sleepForTimeInterval:2.0];</code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"董铂然 come here"</code></code><code class="objc plain"><code class="objc plain">);</code></code></td> </tr> </tbody> </table><p><p>Run results</p></p><p><p></p></p><p><p>The result of this operation is identical to the 1th serial queue, which executes synchronously. Because the concept of synchronous tasks is executed sequentially, and so on Later. The implication is that multiple threads are not allowed. Synchronous and asynchronous is the decision to open a bar or open more than One.</p></p><p><p>So once the synchronization is performed, there is no difference in what queue is Ahead.</p></p>5. Home row, Asynchronous execution <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="gutter">1234567891011</td> <td class="code"><code class="objc comments"><code class="objc comments">// 1. 主队列 - 程序启动之后已经存在主线程,主队列同样存在</code></code><code class="objc plain"><code class="objc plain">dispatch_queue_t q = dispatch_get_main_queue();</code></code><code class="objc comments"><code class="objc comments">// 2. 安排一个任务</code></code><code class="objc keyword"><code class="objc keyword">for</code></code><code class="objc plain"><code class="objc plain">(</code></code><code class="objc datatypes"><code class="objc datatypes">int</code></code><code class="objc plain"><code class="objc plain">i = 0; i<10; i++) {</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">dispatch_async(q, ^{</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"%@ %d"</code></code><code class="objc plain"><code class="objc plain">, [</code></code><code class="objc keyword"><code class="objc keyword">NSThread</code></code><code class="objc plain"><code class="objc plain">currentThread], i);</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">});</code></code><code class="objc plain"><code class="objc plain">}</code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"睡会"</code></code><code class="objc plain"><code class="objc plain">);</code></code><code class="objc plain"><code class="objc plain">[</code></code><code class="objc keyword"><code class="objc keyword">NSThread</code></code><code class="objc plain"><code class="objc plain">sleepForTimeInterval:2.0];</code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"董铂然 come here"</code></code><code class="objc plain"><code class="objc plain">);</code></code></td> </tr> </tbody> </table><p><p>Run results</p></p><p><p></p></p><p><p>The results are a little surprising. The main thread does not print until after sleep, and the loop is Waiting. Because the task of the home row is added to the main thread, if the main thread thread also has a task, it must wait until the main thread task finishes executing before the home row is Executed.</p></p>6. Home row, Synchronous execution <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="gutter">123456789</td> <td class="code"><code class="objc plain">dispatch_queue_t q = dispatch_get_main_queue();</code><code class="objc keyword">NSLog</code><code class="objc plain">(@</code><code class="objc string">"卡死了吗?"</code><code class="objc plain">);</code> <code class="objc plain">dispatch_sync(q, ^{</code><code class="objc spaces"> </code><code class="objc keyword">NSLog</code><code class="objc plain">(@</code><code class="objc string">"我来了"</code><code class="objc plain">);</code><code class="objc plain">});</code><code class="objc keyword">NSLog</code><code class="objc plain">(@</code><code class="objc string">"董铂然 come here"</code><code class="objc plain">);</code></td> </tr> </tbody> </table><p><p>The result of the operation is a dead card</p></p><p><p>The cause of the death is the loop waiting, the main line of things to wait for the primary thread to finish, and because it is synchronous execution can not be the thread, so the following tasks to wait for the above task to finish, so the card is Dead. This is the only combination of the permutations that will Die.</p></p>7. Usage Scenarios for synchronization tasks <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="gutter">123456789101112131415</td> <td class="code"><code class="objc plain"><code class="objc plain">dispatch_queue_t q = dispatch_queue_create(</code></code><code class="objc string"><code class="objc string">"dantesx"</code></code><code class="objc plain"><code class="objc plain">, DISPATCH_QUEUE_CONCURRENT);</code></code><code class="objc comments"><code class="objc comments">// 1. 用户登录,必须要第一个执行</code></code><code class="objc plain"><code class="objc plain">dispatch_sync(q, ^{</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">[</code></code><code class="objc keyword"><code class="objc keyword">NSThread</code></code><code class="objc plain"><code class="objc plain">sleepForTimeInterval:2.0];</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"用户登录 %@"</code></code><code class="objc plain"><code class="objc plain">, [</code></code><code class="objc keyword"><code class="objc keyword">NSThread</code></code><code class="objc plain"><code class="objc plain">currentThread]);</code></code><code class="objc plain"><code class="objc plain">});</code></code><code class="objc comments"><code class="objc comments">// 2. 扣费</code></code><code class="objc plain"><code class="objc plain">dispatch_async(q, ^{</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"扣费 %@"</code></code><code class="objc plain"><code class="objc plain">, [</code></code><code class="objc keyword"><code class="objc keyword">NSThread</code></code><code class="objc plain"><code class="objc plain">currentThread]);</code></code><code class="objc plain"><code class="objc plain">});</code></code><code class="objc comments"><code class="objc comments">// 3. 下载</code></code><code class="objc plain"><code class="objc plain">dispatch_async(q, ^{</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"下载 %@"</code></code><code class="objc plain"><code class="objc plain">, [</code></code><code class="objc keyword"><code class="objc keyword">NSThread</code></code><code class="objc plain"><code class="objc plain">currentThread]);</code></code><code class="objc plain"><code class="objc plain">});</code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"董铂然 come here"</code></code><code class="objc plain"><code class="objc plain">);</code></code></td> </tr> </tbody> </table><p><p>Run results</p></p><p><p></p></p><p><p>The results show that "user login" is printed on the main thread, and the latter two are printed on the async threads. The "user login" above uses synchronous execution, and subsequent charges and downloads are performed asynchronously. So "user login" must first print out no matter how long it takes, then the two async and main thread later print will be printed in an indeterminate order. This is the daily development, those who have dependencies on it must perform the task first, and then perform the order anyway, regardless of the use of asynchronous Execution.</p></p>8.block Asynchronous Task Wrap Synchronization task <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="gutter">1234567891011121314151617181920</td> <td class="code"><code class="objc plain"><code class="objc plain">dispatch_queue_t q = dispatch_queue_create(</code></code><code class="objc string"><code class="objc string">"dantesx"</code></code><code class="objc plain"><code class="objc plain">, DISPATCH_QUEUE_CONCURRENT);</code></code><code class="objc datatypes"><code class="objc datatypes">void</code></code><code class="objc plain"><code class="objc plain">(^task)() = ^ {</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc comments"><code class="objc comments">// 1. 用户登录,必须要第一个执行</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">dispatch_sync(q, ^{</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"用户登录 %@"</code></code><code class="objc plain"><code class="objc plain">, [</code></code><code class="objc keyword"><code class="objc keyword">NSThread</code></code> <code class="objc plain"><code class="objc plain">currentThread]);</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">});</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc comments"><code class="objc comments">// 2. 扣费</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">dispatch_async(q, ^{</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"扣费 %@"</code></code><code class="objc plain"><code class="objc plain">, [</code></code><code class="objc keyword"><code class="objc keyword">NSThread</code></code><code class="objc plain"><code class="objc plain">currentThread]);</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">});</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc comments"><code class="objc comments">// 3. 下载</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">dispatch_async(q, ^{</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"下载 %@"</code></code><code class="objc plain"><code class="objc plain">, [</code></code><code class="objc keyword"><code class="objc keyword">NSThread</code></code><code class="objc plain"><code class="objc plain">currentThread]);</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">});</code></code><code class="objc plain"><code class="objc plain">};</code></code> <code class="objc plain"><code class="objc plain">dispatch_async(q, task);</code></code><code class="objc plain"><code class="objc plain">[</code></code><code class="objc keyword"><code class="objc keyword">NSThread</code></code><code class="objc plain"><code class="objc plain">sleepForTimeInterval:1.0];</code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"董铂然 come here"</code></code><code class="objc plain"><code class="objc plain">);</code></code></td> </tr> </tbody> </table><p><p>Run results</p></p><p><p></p></p><p><p>Because the entire block is executed asynchronously, even if the "user login" is executed synchronously, it can not be executed in the main thread, only open an asynchronous thread execution, because it is synchronous, so he must wait for him to execute first, after the "deduction" and "download" in the above synchronous execution, after the end of the sequence is not determined to print.</p></p>9. Global Queue <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="gutter">123456789</td> <td class="code"><code class="objc plain"><code class="objc plain">dispatch_queue_t q = dispatch_get_global_queue(0, 0);</code></code><code class="objc keyword"><code class="objc keyword">for</code></code><code class="objc plain"><code class="objc plain">(</code></code><code class="objc datatypes"><code class="objc datatypes">int</code></code><code class="objc plain"><code class="objc plain">i = 0; i < 10; i++) {</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">dispatch_async(q, ^{</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"%@ %d"</code></code><code class="objc plain"><code class="objc plain">, [</code></code><code class="objc keyword"><code class="objc keyword">NSThread</code></code><code class="objc plain"><code class="objc plain">currentThread], i);</code></code><code class="objc spaces"><code class="objc spaces"> </code></code><code class="objc plain"><code class="objc plain">});</code></code><code class="objc plain"><code class="objc plain">}</code></code><code class="objc plain"><code class="objc plain">[</code></code><code class="objc keyword"><code class="objc keyword">NSThread</code></code> <code class="objc plain"><code class="objc plain">sleepForTimeInterval:1.0];</code></code><code class="objc keyword"><code class="objc keyword">NSLog</code></code><code class="objc plain"><code class="objc plain">(@</code></code><code class="objc string"><code class="objc string">"com here"</code></code><code class="objc plain"><code class="objc plain">);</code></code></td> </tr> </tbody> </table><p><p>Run results</p></p><p><p></p></p><p><p>The essence of the global queue is the concurrent queue, just after the addition, "quality of service", and "scheduling priority" two parameters, These two parameters generally for the adaptation between the system, it is best to fill in 0 and 0 directly.</p></p><p><p>If you don't see this article in the Dong Platinum blog park, Please click here to view the original</p></p>Summarize:<p><p><strong>1. Open the thread, depending on the function of the execution of the task, synchronization is not open, asynchronous Open.</strong></p></p><p><p><strong>2. Open a few threads, depending on the queue, serial open a line, and open multiple (asynchronous)</strong></p></p><p><p><strong>3. Home Column: A "queue" dedicated to scheduling tasks on the main thread, the home column cannot dispatch tasks in other threads!</strong></p></p><p><p><strong>4. If a task is currently being performed on the main thread, the home column will not dispatch the execution of the task temporarily! The primary queue synchronization task causes a Deadlock. The reason is that the loop waits</strong></p></p><p><p><strong>5. The synchronization task can queue up multiple asynchronous tasks, specify a synchronization task, and let all asynchronous tasks wait for the synchronization task to complete, which is the dependency relationship.</strong></p></p><p><p><strong>6. Global Queue: concurrency, ability to schedule multiple threads, high execution efficiency, but relatively low power costs. The serial queue is inefficient, saves power, or requires dependencies between tasks and can use a serial Queue.</strong></p></p><p><p><strong>7. You can also determine the number of threads to open by judging the current User's network Environment. WiFi under 6, 3g/4g under two or three.</strong></p></p><p><p>An analysis of the results of permutations and combinations of queues and executions in iOS multi-threading</p></p></span>
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.