C++  线程(串行 并行 同步 异步)详解

 更新时间:2017年07月03日 11:31:03   作者:Love@YR  
这篇文章主要介绍了C++ 线程(串行 并行 同步 异步)详解的相关资料,需要的朋友可以参考下

C++  线程(串行 并行 同步 异步)详解

看了很多关于这类的文章,一直没有总结。不总结的话就会一直糊里糊涂,以下描述都是自己理解的非官方语言,不一定严谨,可当作参考。

首先,进程可理解成一个可执行文件的执行过程。在ios app上的话我们可以理解为我们的app的.ipa文件执行过程也即app运行过程。杀掉app进程就杀掉了这个app在系统里运行所占的内存。

线程:线程是进程的最小单位。一个进程里至少有一个主线程。就是那个main thread。非常简单的app可能只需要一个主线程即UI线程。当然大部分还是会有一些子线程的,比如如果你用了AFNetWorking,你的请求都是开辟了子线程。

关于串行,并行,同步,异步,我还是以下面代码的方式做个说明。

首先button点击事件运行在主线程里,先是在主线程里做了打印了一句话,然后创建了一个串行或者并行的队列,之后连续创建了3个同步或者异步的block任务放入此队列中,最后再在主线程里打印一句话。

- (IBAction)serialSync:(id)sender {
 NSLog(@"start log in main thread"]);
  dispatch_queue_t myQueue = dispatch_queue_create("myQueue", NULL);
  for (NSInteger n = 0; n < 3; n++) {
    dispatch_sync(myQueue, ^{
      for (NSInteger i = 0; i < 500000000; i++) {
        if (i == 0) {
          NSLog(@"串行同步任务%ld -> 开始%@",n,[NSThread currentThread]);
        }
        if (i == 499999999) {
          NSLog(@"串行同步任务%ld -> 完成",(long)n);
        }
      }
    });
  }
  NSLog(@"阻塞我没有?当前线程%@",[NSThread currentThread]);
}

- (IBAction)serialAsync:(id)sender {
  NSLog(@"start log in main thread"]);
  dispatch_queue_t myQueue = dispatch_queue_create("myQueue", NULL);//创建一个串行队列
  for (NSInteger n = 0; n < 3; n++) {
    dispatch_async(myQueue, ^{
      for (NSInteger i = 0; i < 500000000; i++) {
        if (i == 0) {
          NSLog(@"串行异步任务%ld -> 开始%@",n,[NSThread currentThread]);
        }
        if (i == 499999999) {
          NSLog(@"串行异步任务%ld -> 完成",(long)n);
        }
      }
    });
  }
  NSLog(@"阻塞我没有?当前线程%@",[NSThread currentThread]);
}

- (IBAction)concurrentSync:(id)sender {
  NSLog(@"start log in main thread"]);
  dispatch_queue_t myQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
  for (NSInteger n = 0; n < 3; n++) {
    dispatch_sync(myQueue, ^{
      for (NSInteger i = 0; i < 500000000; i++) {
        if (i == 0) {
          NSLog(@"并行同步任务%ld -> 开始%@",(long)n,[NSThread currentThread]);
        }
        if (i == 499999999) {
          NSLog(@"并行同步任务%ld -> 完成",(long)n);
        }
      }
    });
  }

  NSLog(@"阻塞我没有?当前线程%@",[NSThread currentThread]);
}
- (IBAction)concurrentAsync:(id)sender {
  NSLog(@"start log in main thread"]);
  dispatch_queue_t myQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
  for (NSInteger n = 0; n < 3; n++) {
    dispatch_async(myQueue, ^{
      for (NSInteger i = 0; i < 500000000; i++) {
        if (i == 0) {
          NSLog(@"并行异步任务%ld -> 开始%@",n,[NSThread currentThread]);
        }
        if (i == 499999999) {
          NSLog(@"并行异步任务%ld -> 完成",(long)n);
        }
      }
    });
  }
  NSLog(@"阻塞我没有?当前线程%@",[NSThread currentThread]);
}

最后的结果如图:

杩欓噷鍐欏浘鐗囨弿杩? title=

其中我把第一句打印和最后一句打印用玫红色表示,它们都运行在当前线程。

方框表示队列,3个block任务分别为3种不同的颜色。

可以看出:

串行即上一个block任务执行完毕下一个任务才加入到队列中。

并行即其中的任务同时加入到队列中。

从运行结果来看

第一个图只有一个主线程:

3个block都是同步即都阻塞当前线程,所以最后那句打印的任务就在3个block运行完之后。

3个block又是串行,所以一个一个运行

第二个图有2个线程即一个主线程一个子线程:

3个block都是异步,没有任务阻塞当前线程。所以最后那句打印是在第一句打印后就可以开始执行的。

3个block都是异步,异步会创建新的线程即至少有一个子线程。

3个block是串行,只有一个任务做完才会加另一个任务入队列,所以只需一个子线程。

第三个图只有一个主线程:

3个block都是同步即都阻塞当前线程,所以最后那句打印的任务就在3个block运行完之后。

3个block是并行,同时被加入队列中。

3个block都是同步,由于同步意味着等待,所以任务的执行表现为顺序执行,其实是一起加进去的但是等待的,跟串行的区别是串行是别的任务做完才把它加进队列中。

第四个图有多个线程:

3个block都是异步,没有任务阻塞当前线程。所以最后那句打印是在第一句打印后就可以开始执行的。

3个block都是异步,异步会创建新的线程即至少有一个子线程。

3个block是并行,需创建多个子线程才能保证任务同时执行。

再看一张图:其中第一个异步为玫红色,两个同步分别以紫色黄色表示,两个异步分别以绿色棕色表示,队列后面的当前线程动作为橘色。虚线代表等待。上面代表串行,下面是并行。

杩欓噷鍐欏浘鐗囨弿杩? title=

由此图可以看出:

同步block会阻塞当前线程,即会在当前线程中运行。(这里的当前线程为主线程所以会看到UI卡住)

异步block会开辟新的线程。

在串行队列中,异步block任务用的是同一个子线程,因为需要等待任务一个一个地执行,不需要多个线程。

在并行队列中,异步block任务同时执行,系统为其分配线程。图中的例子因第一个异步操作在第二个开始前已经结束了,所以并不是多少个异步操作就创建多少线程,主要还是看需要。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

相关文章

  • 直观理解C语言中指向一位数组与二维数组的指针

    直观理解C语言中指向一位数组与二维数组的指针

    这篇文章主要介绍了直观理解C语言中指向一位数组与二维数组的指针,数组指针是C语言入门学习过程中的重点和难点,需要的朋友可以参考下
    2016-05-05
  • C++中引用传递与指针传递的区别(面试常见)

    C++中引用传递与指针传递的区别(面试常见)

    这篇文章主要介绍了C++中引用传递与指针传递的区别(面试常见),需要的朋友可以参考下
    2018-03-03
  • Qt学习教程之对话框消失动画效果

    Qt学习教程之对话框消失动画效果

    这篇文章主要给大家介绍了关于Qt学习教程之对话框消失动画效果的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-07-07
  • C语言 文件的打开与关闭详解及示例代码

    C语言 文件的打开与关闭详解及示例代码

    本文主要介绍C语言 文件的基础知识,这里整理了相关资料及示例代码,有兴趣的小伙伴可以参考下
    2016-08-08
  • C++中String的语法及常用接口的底层实现详解

    C++中String的语法及常用接口的底层实现详解

    在C语言中,string是一个标准库类(class),用于处理字符串,它提供了一种更高级、更便捷的字符串操作方式,string 类提供了一系列成员函数和重载运算符,以便于对字符串进行操作和处理,本编文章会对C++中的 string 进行详解,希望本篇文章会对你有所帮助
    2023-06-06
  • C++中auto_ptr智能指针的用法详解

    C++中auto_ptr智能指针的用法详解

    这篇文章主要介绍了C++中auto_ptr智能指针的用法详解的相关资料,需要的朋友可以参考下
    2016-07-07
  • C++异常使用详解(看这一篇就够了)

    C++异常使用详解(看这一篇就够了)

    C++中的异常是指在程序执行过程中发生错误,导致程序无法正常运行的情况,下面这篇文章主要给大家介绍了关于C++异常使用的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-10-10
  • 快速掌握VC6.0中各种宏注释应用(附图)

    快速掌握VC6.0中各种宏注释应用(附图)

    为了方便别人或自己阅读自己的程序,注释是坚决不可少的,一个漂亮的程序,不是在于你应用的技术多么高深,而是能够把高深的技术描述的清楚易懂
    2013-01-01
  • C/C++ Qt Tree与Tab组件实现分页菜单功能

    C/C++ Qt Tree与Tab组件实现分页菜单功能

    这篇文章主要介绍了C/C++ Qt Tree与Tab组件实现分页菜单功能,实现一个类似于树形菜单栏的功能,当用户点击菜单栏中的选项时则会跳转到不同的页面上,本文简单给大家分享实现代码,感兴趣的朋友跟随小编一起看看吧
    2021-11-11
  • C语言扫雷游戏的简单实现

    C语言扫雷游戏的简单实现

    这篇文章主要为大家详细介绍了C语言扫雷游戏的简单实现,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11

最新评论