[iOS开发]pthread、NSThread

本文详细介绍了pthread和NSThread在iOS开发中的使用,包括线程创建、启动、状态控制和通讯。讨论了线程安全问题,展示了如何在不同线程间进行通讯,确保在多线程环境中正确更新UI。同时,文章还提供了示例代码,帮助理解pthread和NSThread的使用差异。
摘要由CSDN通过智能技术生成

pthread

pthread是一套通用的多线程API,可以在Unix/Linux/Windows等系统跨平台使用。使用C语言编写,需要程序员自己管理线程的生命周期,使用难度比极大,我们在iOS开发中几乎不适用pthread,但是我们可以来了解一下。

  • 头文件#import <pthread.h>
  • 创建线程,并开启线程执行任务
pthread_create()创建一个线程
pthread_exit()终止当前线程
pthread_cancel()中断另外一个线程的运行
pthread_join() 阻塞当前的线程,直到另外一个线程运行结束
pthread_attr_init()初始化线程的属性
pthread_attr_setdetachstate()设置脱离状态的属性(决定这个线程在终止时是否可以被结合)
pthread_attr_getdetachstate() 获取脱离状态的属性
pthread_attr_destroy() 删除线程的属性
pthread_kill() 向线程发送一个信号
void * run(void *param) {    // 新线程调用方法,里边为需要执行的任务{
   NSLog(@"%@", [NSThread currentThread]);

   return NULL;
}

int main(int argc, const char * argv[]) {
    // 1. 创建线程: 定义一个pthread_t类型变量
    pthread_t thread;
    // 2. 开启线程: 执行任务
    pthread_create(&thread, NULL, run, NULL);
    // 3. 设置子线程的状态设置为 detached,该线程运行结束后会自动释放所有资源
    pthread_detach(thread);
    NSLog(@"%@",[NSThread currentThread]);//如果不要这一行,很可能直接return 0,线程还没调用,直接return 0了
    return 0;
}
create中间有4个参数
第一个:线程对象,指向线程标识符的指针
第二个:线程属性,默认为NULL
第三个:指向函数的指针,新创建的线程从run函数地址开始运行
第四个:默认为NULL,如果需要参数,将地址传入

NSThread

NSThread是苹果官方提供的线程,使用起来比pthread更加面向对象,简单易用,可以直接操作线程对象。不过也需要程序员自己管理线程的生命周期(主要是创建)。

创建、启动线程

先创建线程,再启动线程

    // 1. 创建线程
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
    // 2. 启动线程
    [thread start];    // 线程一启动,就会在线程thread中执行self的run方法
    
    // 新线程调用方法,里边为需要执行的任务
- (void)run {
    NSLog(@"%@", [NSThread currentThread]);
}

创建线程后自动启动线程

    // 1. 创建线程后自动启动线程
[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];

    
    // 新线程调用方法,里边为需要执行的任务
- (void)run {
    NSLog(@"%@", [NSThread currentThread]);
}

隐式创建并启动线程

[self performSelectorInBackground:@selector(run) withObject:nil];

    // 新线程调用方法,里边为需要执行的任务
- (void)run {
    NSLog(@"%@", [NSThread currentThread]);
}

线程的相关用法

获得主线程
+ (NSThread *)mainThread;

判断是否为主线程
- (BOOL)isMainThread;
+ (BOOL)isMainThread;

获得当前线程
NSThread *current = [NSThread currentThread];

线程的名字——setter方法
- (void)setName:(NSString *)n;

线程的名字——getter方法
- (NSString *)name;

线程状态控制方法

启动方法

线程由就绪态变成运行态。当线程任务执行完毕,自动进入死亡状态
- (void)start;

阻塞(暂停)线程方法

+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;//这里的参数是NSTimeInterval类型的,其值始终是以秒为单位的,直接用数字就行了
// 线程进入阻塞状态

强制停止线程

程序进入死亡状态
+ (void)exit;

线程之间的通讯

我们常常会在子线程进行耗时操作,操作结束后回到主线程刷新UI。
这就涉及到了子线程和主线程之间的通信

在主线程上执行操作
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelectorOnMainThread:(SEL)aSelector WithObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray<NSString *> *)array;

在指定线程上执行操作
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array NS_AVAILABLE(10_5, 2_0);
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait NS_AVAILABLE(10_5, 2_0);

在当前线程上执行操作,调用NSObject的performSelector:相关方法
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;

我们用的最多的就是回到主线程
现在我们学习到了


dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 需要在主线程执行的代码
});


performSelectorOnMainThread

[self performSelectorOnMainThread:@selector(WantToGoBackMianThread:) withObject:@"1" waitUntilDone:YES];

selector:执行的方法
arg:传给方法的参数
wait:为NO,不阻塞主线程的执行
	 为YES,阻塞主线程的执行

- (void)WantToGoBackMianThread:(id)object{
     //需要在主线程执行的代码
    NSLog(@"object:%@",object);
}

线程安全

涉及到线程安全就要考虑加锁了

在这里插入图片描述

iOS加锁的方式有很多种

以@synchronized为例,为NSThread加锁

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值