一、在工作的代码有一段while-True轮训的逻辑,循环中主要的工作是阻塞的IO

  代码大概如下:

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
while (YES) { NSLog(@"CPU %f", cpu_usage()); [NSThread sleepForTimeInterval:1];
}
});

  正常的时候,因为io的阻塞关系,线程会在io的方法处等待返回,偶然发现特定情况下,阻塞io方法直接放回错误,这样会不停的进行死循环,因此我想看看死循环会带来什么问题

  我写了下面的代码

  

//
// ViewController.m
// TestCPU
//
// Created by lilun on 2019/3/20.
// Copyright 2019年 lilun. All rights reserved.
// #import "ViewController.h"
#import <mach/mach.h>
#import <assert.h> float cpu_usage()
{
kern_return_t kr;
task_info_data_t tinfo;
mach_msg_type_number_t task_info_count; task_info_count = TASK_INFO_MAX;
kr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)tinfo, &task_info_count);
if (kr != KERN_SUCCESS) {
return -1;
} task_basic_info_t basic_info;
thread_array_t thread_list;
mach_msg_type_number_t thread_count; thread_info_data_t thinfo;
mach_msg_type_number_t thread_info_count; thread_basic_info_t basic_info_th;
uint32_t stat_thread = 0; // Mach threads basic_info = (task_basic_info_t)tinfo; // get threads in the task
kr = task_threads(mach_task_self(), &thread_list, &thread_count);
if (kr != KERN_SUCCESS) {
return -1;
}
if (thread_count > 0)
stat_thread += thread_count; long tot_sec = 0;
long tot_usec = 0;
float tot_cpu = 0;
int j; for (j = 0; j < (int)thread_count; j++)
{
thread_info_count = THREAD_INFO_MAX;
kr = thread_info(thread_list[j], THREAD_BASIC_INFO,
(thread_info_t)thinfo, &thread_info_count);
if (kr != KERN_SUCCESS) {
return -1;
} basic_info_th = (thread_basic_info_t)thinfo; if (!(basic_info_th->flags & TH_FLAGS_IDLE)) {
tot_sec = tot_sec + basic_info_th->user_time.seconds + basic_info_th->system_time.seconds;
tot_usec = tot_usec + basic_info_th->user_time.microseconds + basic_info_th->system_time.microseconds;
tot_cpu = tot_cpu + basic_info_th->cpu_usage / (float)TH_USAGE_SCALE * 100.0;
} } // for each thread kr = vm_deallocate(mach_task_self(), (vm_offset_t)thread_list, thread_count * sizeof(thread_t));
assert(kr == KERN_SUCCESS); return tot_cpu;
} @interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.3 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self runOneThread:1];
// [self runOneThread:2];
// [self runOneThread:3];
// [self runOneThread:4];
}); UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 100)];
label.textColor = [UIColor redColor];
label.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:label];
label.center = self.view.center;
label.tag = 1234; dispatch_async(dispatch_get_global_queue(0, 0), ^{
while (YES) { NSLog(@"CPU %f", cpu_usage()); dispatch_async(dispatch_get_main_queue(), ^{
UILabel *label = [self.view viewWithTag:1234];
label.text = [NSString stringWithFormat:@"CPU %f", cpu_usage()];
}); [NSThread sleepForTimeInterval:1];
}
}); } - (void)runOneThread:(NSInteger)i
{ dispatch_async(dispatch_get_global_queue(0, 0), ^{ while (YES) {
NSLog(@"run thread %ld", i);
}
}); } @end

  上面的代码如果运行在模拟器的时候,大概4核的cpu(400%)会占据40%的CPU,还不是很多,貌似模拟器的CPU占用会限制。

    此时电脑风扇会呼呼转。

  上面的代码是真机调试的状态下,会出现调试器卡死,Xcode无反应,必须拔掉USB线来中断调试。

    猜测原因是循环输出的log占满了USB通信的带宽,导致调试信息无法传递到Xcode上。或者是调试线程因为工作线程导致无法工作正常

  如果是非调试模式下面,大概会占用98%(以上的方法测试出来)的CPU,机器会发烫。

    应该极力避免出现死循环的情况,即使是在子线程中出现的死循环。

总结:

  死循环在子线程也是不能出现的,任何方法一定要限制好频率。

  NSlog会产生系统中断,频繁的系统中断也会导致性能低下。  

    

  

iOS线程While-True死循环会发生什么的更多相关文章

  1. iOS 线程安全

    线程安全: 当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题.就好比几个人在同一时修改同一个表格,造成数据的错乱. 解决多线程安全问题的方法 方法一:互斥锁(同步锁) @synchroni ...

  2. iOS线程之——NSCondition

    多线程在各种编程语言中都是难点,很多语言中实现起来很麻烦,objective-c虽然源于c,但其多线程编程却相当简单,可以与java相媲美.这篇文章主要从线程创建与启动.线程的同步与锁.线程的交互.线 ...

  3. 面试刷题17:线程两次start()会发生什么?

    线程是并发编程的基础元素,是系统调度的最小单元,现代的jvm直接对应了内核线程.为了降低并发编程的门槛,go语言引入了协程. 你好,我是李福春,我在准备面试,今天的题目是? 一个线程两次调用start ...

  4. IOS 线程处理 子线程

    IOS 线程处理 子线程的启动与结束 技术交流新QQ群:414971585   IOS中,如果要在主线程中启动一个子线程,可以又两种方法: [NSThread detachNewThreadSelec ...

  5. while true 死循环判断端口按顺序启动应用

    需求:spring微服务应用启动较慢并且要求一个应用启完才能启第二个应用. 思路:加了个while true 死循环判断端口启动了才启下一个应用. 执行方式:/appupgrade/spring_cl ...

  6. iOS 线程操作库 PromiseKit

    iOS 线程操作库 PromiseKit 官网:http://promisekit.org/ github:https://github.com/mxcl/PromiseKit/tree/master ...

  7. while True 死循环

    while True 死循环示例: count = 0 #给count设置变量为0 while True: count += 1 #每循环一次,count+1 : count += 1 等同于coun ...

  8. c# 线程启动while(true) 死循环,里边的return导致线程退出情况,查错

    写了一个线程 线程下启动了一个循环 while(true) { 里边有个判断 如果为空不操作, 有余这个线程是后加的,老程序里边因为有个return没关注,导致线程退出而不能不听的监控 } 线程启动一 ...

  9. iOS 线程安全--锁

    一,前言 线程安全是iOS开发中避免了的话题,随着多线程的使用,对于资源的竞争以及数据的操作都可能存在风险,所以有必要在操作时保证线程安全. 二,为什么要使用锁? 由于一个进程中不可避免的存在多线程, ...

  10. iOS: 线程中那些常见的锁

    一.介绍 在多线程开发中,锁的使用基本必不可少,主要是为了解决资源共享时出现争夺而导致数据不一致的问题,也就是线程安全问题.锁的种类很多,在实际开发中,需要根据情况选择性的选取使用,毕竟使用锁也是消耗 ...

随机推荐

  1. Centos7、CentOS8、CentOS9 修改硬盘分区大小扩充root分区大小

    Centos7 修改硬盘分区大小,实现CentOS无损分区扩容 扩充root分区大小 安装了CentOS7 开发环境及软件后,发现root分区已经才剩下不到1G空间,难不成要干掉重装,OMG,NO! ...

  2. vue watch的this 到底是什么?

    正文 watch: { value: (newV, oldV) => { this.a = newV; } } 加入该vue对象中,data 有: { data:{ a:5 } } 那么请问,如 ...

  3. 密码学系列——数字签名(c# 代码实操)

    前言 结合消息摘要.非对称加密.数字签名三篇,进行代码实操. 代码完整,可复制运行. 正文 代码如下: public class SignatureHelper { /// <summary&g ...

  4. 什么是ip协议一

    前言 两节结束,为网络底层系列做铺垫. 首先来看一张图: IOS有七层,但是我们可以简化层4层,ip属于传输层,可以说是非常重要,下面简单的做一个介绍. 正文 ip的介绍: 1.ip是tcp/ip 协 ...

  5. szfpga 详细:高云1N1开发板高云gowin软件使用教程

      1.概述 国产FPGA是最近几年起来的产品,具有性价比高特点.高云FPGA,大多用在LED,电机控制,PLC设备上. 高云1N1开发板采用GW1N-LV1QN48C6/I5 FPGA器件.具有低功 ...

  6. css3新单位vw、vh、vmin、vmax的使用详解

    1,vw.vh.vmin.vmax 的含义 (1) vw. vh. vmin. vmax 是一种视窗单位,也是相对单位.它相对的不是父节点或者页面的根节点.而是由视窗( Viewport)大小来决定的 ...

  7. easyx的使用 鼠标交互(3.1)

    本文学习于B站,进行借鉴学习记录: 视频链接:鼠标操作(新版)_哔哩哔哩_bilibili 初始化调用文件头不再使用#include<graphics.h>,选择调用#include< ...

  8. 力扣1098(MySQL)-小众书籍(中等)

    题目: 书籍表 Books: book_id 是这个表的主键 订单表 Orders: order_id 是这个表的主键.book_id 是 Books 表的外键. 问题你需要写一段 SQL 命令,筛选 ...

  9. 亿图version 9.2安装教程

    记录一下自己安装亿图9.2版本的安装过程~ 先获取安装资料: 百度网盘链接: 链接:https://pan.baidu.com/s/1zJDcF9Y0Xy2CvD4mG_oOfQ?pwd=pqy9 提 ...

  10. 写给大家看的“不负责任” K8s 入门文档

    前言 2019 年下半年,我做了一次转岗,开始接触到 Kubernetes,虽然对 K8s 的认识还非常的不全面,但是非常想分享一下自己的一些收获,希望通过本文能够帮助大家对 K8s 有一个入门的了解 ...