iOS线程While-True死循环会发生什么
一、在工作的代码有一段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死循环会发生什么的更多相关文章
- iOS 线程安全
线程安全: 当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题.就好比几个人在同一时修改同一个表格,造成数据的错乱. 解决多线程安全问题的方法 方法一:互斥锁(同步锁) @synchroni ...
- iOS线程之——NSCondition
多线程在各种编程语言中都是难点,很多语言中实现起来很麻烦,objective-c虽然源于c,但其多线程编程却相当简单,可以与java相媲美.这篇文章主要从线程创建与启动.线程的同步与锁.线程的交互.线 ...
- 面试刷题17:线程两次start()会发生什么?
线程是并发编程的基础元素,是系统调度的最小单元,现代的jvm直接对应了内核线程.为了降低并发编程的门槛,go语言引入了协程. 你好,我是李福春,我在准备面试,今天的题目是? 一个线程两次调用start ...
- IOS 线程处理 子线程
IOS 线程处理 子线程的启动与结束 技术交流新QQ群:414971585 IOS中,如果要在主线程中启动一个子线程,可以又两种方法: [NSThread detachNewThreadSelec ...
- while true 死循环判断端口按顺序启动应用
需求:spring微服务应用启动较慢并且要求一个应用启完才能启第二个应用. 思路:加了个while true 死循环判断端口启动了才启下一个应用. 执行方式:/appupgrade/spring_cl ...
- iOS 线程操作库 PromiseKit
iOS 线程操作库 PromiseKit 官网:http://promisekit.org/ github:https://github.com/mxcl/PromiseKit/tree/master ...
- while True 死循环
while True 死循环示例: count = 0 #给count设置变量为0 while True: count += 1 #每循环一次,count+1 : count += 1 等同于coun ...
- c# 线程启动while(true) 死循环,里边的return导致线程退出情况,查错
写了一个线程 线程下启动了一个循环 while(true) { 里边有个判断 如果为空不操作, 有余这个线程是后加的,老程序里边因为有个return没关注,导致线程退出而不能不听的监控 } 线程启动一 ...
- iOS 线程安全--锁
一,前言 线程安全是iOS开发中避免了的话题,随着多线程的使用,对于资源的竞争以及数据的操作都可能存在风险,所以有必要在操作时保证线程安全. 二,为什么要使用锁? 由于一个进程中不可避免的存在多线程, ...
- iOS: 线程中那些常见的锁
一.介绍 在多线程开发中,锁的使用基本必不可少,主要是为了解决资源共享时出现争夺而导致数据不一致的问题,也就是线程安全问题.锁的种类很多,在实际开发中,需要根据情况选择性的选取使用,毕竟使用锁也是消耗 ...
随机推荐
- 如何用vsftpd实现用户不同权限:只能下载,可上传,管理权限等 [仅供参考未亲测]
如何用vsftpd实现用户不同权限:只能下载,可上传,管理权限等 2007-01-29 10:20:09 分类: LINUX 前提条件: 必须安装包:vsftpd-2.0.1-5 ...
- 常见的PLC通信协议及相关介绍
2023-07-26 一.常见的PLC通信协议: Modbus:Modbus是一种串行通信协议,它支持多种物理层接口(如RS-232.RS-485等),可以实现PLC与其他设备(如HMI.变频器等)之 ...
- shell编程实现用户循环输入
如果你想在Shell脚本中实现一个循环判断用户输入是否正确,并根据情况决定是否退出系统,可以使用一个无限循环(如while true)和条件语句来实现. 以下是一个示例代码,用于演示这种情况: #!/ ...
- 百万TPS高吞吐、秒级低延迟,阿里搜索离线平台如何实现?
导读:阿里主搜(淘宝天猫搜索)是搜索离线平台非常重要的一个业务,具有数据量大.一对多的表很多.源表的总数多和热点数据等特性.对于将主搜这种逻辑复杂的大数据量应用迁移到搜索离线平台总是不缺少性能的挑战, ...
- 企业版Spark Databricks + 企业版Kafka Confluent 联合高效挖掘数据价值
简介:本文介绍了如何使用阿里云的Confluent Cloud和Databricks构建数据流和LakeHouse,并介绍了如何使用Databricks提供的能力来挖掘数据价值,使用Spark ML ...
- 阿里的 RocketMQ 如何让双十一峰值之下 0 故障?
简介: 2020 年双十一交易峰值达到 58.3 W 笔/秒,消息中间件 RocketMQ 继续数年 0 故障丝般顺滑地完美支持了整个集团大促的各类业务平稳. 作者 | 愈安来源 | 阿里巴巴云原生公 ...
- [FAQ] pdf 无法导入 adobe AI, 分辨率 or 颜色缺失 or 字体缺失
属于Adoge软件不支持问题, 可能是分辨率.字体等多种原因. https://www.codebye.com/adobe-reader-or-acrobat-opens-pdf-file-drawi ...
- dotnet SemanticKernel 入门 注入日志
使用 SemanticKernel 框架在对接 AI 时,由于使用到了大量的魔法,需要有日志的帮助才好更方便定位问题,本文将告诉大家如何在 SemanticKernel 注入日志 本文属于 Seman ...
- C# 获取指定文件夹中所有的文件(包括子文件夹的文件)
有个需求中需要播放指定路径的声音,但你必须要有该路径的声音才可以播放,如果没有该文件则播放默认的声音,该方法用于初始化应用的时候获取指定目录的所有文件,便于后来播放声音的时判断路径是否存在. usin ...
- ABAP 7.55 新特性 (二) ABAP SQL部分
上一篇文章ABAP 7.55 新特性 (一)介绍了ABAP 7.55中除ABAP SQL外的更新内容,本篇是剩余的ABAP SQL更新部分. 本文链接:https://www.cnblogs.com/ ...