多线程(一)

前些天复习了下多线程,一直忙于项目,今天抽空整理下,以后可以看:
PThread

没有过多深究,在项目中几乎不用,可能研究过还是很快会忘记,我觉得知道大概就可以了,用到时再研究:

POSIX线程(POSIX threads),简称Pthreads,是线程的POSIX标准。该标准定义了创建和操纵线程的一整套API。在类Unix操作系统(Unix、Linux、Mac OS X等)中,都使用Pthreads作为操作系统的线程。Windows操作系统也有其移植版pthreads-win32[1] 。

作用:线程库实行了POSIX线程标准通常称为Pthreads。POSIX线程具有很好的可移植性,使用pthreads编写的代码可运行于Solaris、FreeBSD、Linux 等平台,Windows平台亦有pthreads-win32可供使用。

数据类型

pthread_t:线程ID
pthread_attr_t:线程属性

操纵函数

pthread_create():创建一个线程
pthread_exit():终止当前线程
pthread_cancel():中断另外一个线程的运行
pthread_join():阻塞当前的线程,直到另外一个线程运行
pthread_attr_init():初始化线程的属性
pthread_attr_setdetachstate():设置脱离状态的属性(决定这个线程在终止时是否可以被结合)
pthread_attr_getdetachstate():获取脱离状态的属性
pthread_attr_destroy():删除线程的属性
pthread_kill():向线程发送一个信号

同步函数

用于 mutex 和条件变量
pthread_mutex_init() 初始化互斥锁
pthread_mutex_destroy() 删除互斥锁
pthread_mutex_lock():占有互斥锁(阻塞操作)
pthread_mutex_trylock():试图占有互斥锁(不阻塞操作)。即,当互斥锁空闲时,将占有该锁;否则,立即返回。
pthread_mutex_unlock(): 释放互斥锁
pthread_cond_init():初始化条件变量
pthread_cond_destroy():销毁条件变量
pthread_cond_signal(): 唤醒第一个调用pthread_cond_wait()而进入睡眠的线程
pthread_cond_wait(): 等待条件变量的特殊条件发生
Thread-local storage(或者以Pthreads术语,称作线程特有数据):
pthread_key_create(): 分配用于标识进程中线程特定数据的键
pthread_setspecific(): 为指定线程特定数据键设置线程特定绑定
pthread_getspecific(): 获取调用线程的键绑定,并将该绑定存储在 value 指向的位置中
pthread_key_delete(): 销毁现有线程特定数据键
pthread_attr_getschedparam();获取线程优先级
pthread_attr_setschedparam();设置线程优先级

工具函数

pthread_equal(): 对两个线程的线程标识号进行比较
pthread_detach(): 分离线程
pthread_self(): 查询线程自身线程标识号

c 语言代码,需要手动管理线程生命周期,不方便
oc中进行测试

导入#import < pthread.h >

//pthread 测试
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

pthread_t * thread;
 pthread_create(&thread, NULL,start, NULL)
//打印结果
//2017-11-06 14:01:48.604 多线程测试  [7087:203258] pthread current thread<NSThread: 0x60800007ba80>{number = 3, name = (null)}}

void * start(void * data) {
 // pthread_self()
NSLog(@"pthread current thread%@",[NSThread currentThread]);
return NULL;
}
NSThread

封装pthread 后,完全面向对象的,可以直接操控对象,简单直观,但是需要我们手动管理线程的声明周期,手动开启和取消,常用[NSThread currentThread] 调试

开启一个线程:

//方法1
NSThread * thread = [[NSThread alloc]initWithTarget:self selector:@selector(creatThread) object:nil];
[thread start];
// 打印信息2017-11-06 14:10:06.865 多线程测试[7225:209398] nsthread <NSThread: 0x600000076e40>{number = 3, name = (null)}

NSThread * firstThred = [[NSThread alloc]initWithBlock:^{
NSLog(@"我是第一个线程%@",[NSThread currentThread]);
}];
//设置线程名字
firstThred.name = @"firstThread";
[firstThred start];

//方法2 [detach: 分派]

[NSThread detachNewThreadSelector:@selector(creatThread) toTarget:self withObject:nil];
//打印信息2017-11-06 14:15:29.865 多线程测试[7290:212552] nsthread <NSThread: 0x6000000733c0>{number = 3, name = (null)}

//block方法(最晚执行)

`[NSThread detachNewThreadWithBlock:^{
    NSLog(@"block detachNewThread%@",[NSThread currentThread]);`

//回到主线程

[self performSelectorOnMainThread:@selector(creatMainThread) withObject:nil waitUntilDone:NO];

//默认当前线程延迟执行

` [self performSelector:@selector(performTest) withObject:nil afterDelay:1.0];

//获取线程的栈地址

NSLog(@"线程的栈地址%@",[NSThread callStackReturnAddresses]);
//线程的栈地址(0x10fd883ba 0x110ec3a3d 0x110ec3e70 0x110d8d4b5 0x110d8dc06 0x110da1519 0x110d19f8d 0x110d200ed 0x110d1d26d 0x113ef96cb 0x113ef9544 0x113ef98cd 0x1108a2761 0x11088798c 0x110886e76 0x110886884 0x110d1baea 0x110d21c68 0x10fd8894f 0x11375f68d 0x1)

`线程执行的符号化
// NSLog(@”线程的符号化%@”,[NSThread callStackSymbols]);

( 0 多线程测试 0x00000001091f63ca -[ViewController viewDidLoad] + 202
// 1 UIKit 0x000000010a331a3d -[UIViewController loadViewIfRequired] + 1258
// 2 UIKit 0x000000010a331e70 -[UIViewController view] + 27
// 3 UIKit 0x000000010a1fb4b5 -[UIWindow addRootViewControllerViewIfPossible] + 71
// 4 UIKit 0x000000010a1fbc06 -[UIWindow _setHidden:forced:] + 293
// 5 UIKit 0x000000010a20f519 -[UIWindow makeKeyAndVisible] + 42
// 6 UIKit 0x000000010a187f8d -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4818
// 7 UIKit 0x000000010a18e0ed -[UIApplication _runWithMainScene:transitionContext:completion:] + 1731
// 8 UIKit 0x000000010a18b26d -[UIApplication workspaceDidEndTransaction:] + 188
// 9 FrontBoardServices 0x000000010d3676cb __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
// 10 FrontBoardServices 0x000000010d367544 -[FBSSerialQueue _performNext] + 189
// 11 FrontBoardServices 0x000000010d3678cd -[FBSSerialQueue _performNextFromRunLoopSource] + 45
// 12 CoreFoundation 0x0000000109d10761 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
// 13 CoreFoundation 0x0000000109cf598c __CFRunLoopDoSources0 + 556
// 14 CoreFoundation 0x0000000109cf4e76 __CFRunLoopRun + 918
// 15 CoreFoundation 0x0000000109cf4884 CFRunLoopRunSpecific + 420
// 16 UIKit 0x000000010a189aea -[UIApplication _run] + 434
// 17 UIKit 0x000000010a18fc68 UIApplicationMain + 159
// 18 多线程测试 0x00000001091f695f main + 111
// 19 libdyld.dylib 0x000000010cbcd68d start + 1
// 20 ??? 0x0000000000000001 0x0 + 1
// )

是否想到dysm:
开发者能获取到错误堆栈信息,而使用atos工具就是把地址对应的具体符号信息找到。它是一个可以把地址转换为函数名(包括行号)的工具,
执行方式如下:
atos -o executable -arch architecture -l loadAddress address

 说明:

 loadAddress 表示函数的动态加载地址,对应崩溃地址堆栈中 +号前面的地址

 address 表示运行时地址、对应崩溃地址堆栈中第一个地址,实际上,崩溃地址堆栈中+号前后的地址相加即是运行时地址

结论
1、NSThread 是苹果封装过的一种多线程,并且完全面向对象,需要自己手动管理开启或取消线程,常用来调试

2、常用以下三种方法开启子线程
i. // NSThread * thread = [[NSThread alloc]initWithTarget:self selector:@selector(creatThread) object:nil];
// [thread start];
ii:// [NSThread detachNewThreadSelector:@selector(creatThread) toTarget:self withObject:nil];
iii:
// [self performSelectorInBackground:@selector(creatThread) withObject:nil];

3、可以通过[self performSelector:<#(nonnull SEL)#> onThread:<#(nonnull NSThread *)#> withObject:<#(nullable id)#> waitUntilDone:<#(BOOL)#>] 或 [self performSelectorOnMainThread:<#(nonnull SEL)#> withObject:<#(nullable id)#> waitUntilDone:<#(BOOL)#>]; 进行线程间的交互

4、通过- (void)performSelector:(SEL)aSelector onThread:(NSThread )thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值