博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS -多线程之pthread
阅读量:4135 次
发布时间:2019-05-25

本文共 2838 字,大约阅读时间需要 9 分钟。

pthread是POSIX thread的简写,一套通用的多线程API,适用于Unix、Linux、Windows等系统,跨平台、可移植,使用难度大的C语言框架,线程生命周期由程序员管理,。在多线程方面iOS有GCD、NSThread、NSOperation,所以开发时pthread几乎用不到,以下就简单运用pthread开启一个子线程,用来处理耗时操作。

导入头文件

想使用pthread开辟子线程必须要导入头文件#import <pthread.h>,函数大多以"pthread_"开头。

常用API介绍

1、pthread_creat()

int pthread_create(pthread_t _Nullable * _Nonnull __restrict,		const pthread_attr_t * _Nullable __restrict,		void * _Nullable (* _Nonnull)(void * _Nullable),		void * _Nullable __restrict)

作用:创建一个线程

参数:

  • 第一个参数:指向线程标识符的指针;
  • 第二个参数:用来设置线程属性,初始化一个pthread_attr_t变量指定优先级等属性,一般可以传入Null;
  • 第三个参数:线程运行函数的起始地址;
  • 最后一个参数:传给运行函数的参数。

返回值:0代表成功。 失败,返回的则是错误号。

2、pthread_join()

int pthread_join(pthread_t , void * _Nullable * _Nullable)

作用:以阻塞的方式等待指定的线程结束。当函数返回时,被等待线程的资源被收回。如果线程已经结束,那么该函数会立即返回。

参数:

  • 第一个参数:线程标识符,即线程ID,标识唯一线程;
  • 第二个参数:用户定义的指针,用来存储被等待线程的返回值。

返回值:0代表成功。 失败,返回的则是错误号。

3、pthread_detach()

int pthread_detach(pthread_t);

作用:将该子线程的状态设置为detached,则该线程运行结束后会自动释放所有资源,与pthread_join的区别在于pthread_detach不会阻塞调用线程。

参数:线程标识符。

4、pthread_kill()

int pthread_kill(pthread_t, int);

作用:向某个线程传递一个信号

参数:

  • 第一个参数:线程的标识符;
  • 第二个参数:传递的signal参数,一般都是大于0的,这时系统默认或者自定义的都是有相应的处理程序。常用信号量宏可以在这里查看,#import <signal.h>,signal为0时,是一个被保留的信号,一般用这个保留的信号测试线程是否存在。

5、pthread_cancel()

int pthread_cancel(pthread_t) __DARWIN_ALIAS(pthread_cancel);

作用:发送终止信号给thread线程,如果成功则返回0,否则为非0值。发送成功并不意味着thread会终止,。

参数:线程的标识符。

pthread创建子线程

- (void)testPThread{
pthread_t thread1; pthread_attr_t att; pthread_attr_init(&att); NSString *name = @"小玉子"; //创建一个线程 int result = pthread_create(&thread1, &att, func1, (__bridge void *)(name)); result == 0 ? NSLog(@"创建线程 OK") : NSLog(@"创建线程失败"); //当前线程被阻塞,等待线程1结束后恢复,如果注释掉会怎么样? pthread_join(thread1, NULL); pthread_t thread2; int a = 2; pthread_create(&thread2, NULL, (void *)func2, &a); pthread_detach(thread2); // 或者在run2中调用pthread_detach(pthread_self());}int a = 100;void *func1 (void *param){
NSLog(@"func1 param = %@",param); for (int i = 0; i<3; i++) {
NSLog(@"---func2--%d---%@",i,[NSThread currentThread]); } return &a;}void func2 (void *param){
NSLog(@"func2 param = %d",(int)(*((int*)param))); for (int i = 0; i<3; i++) {
NSLog(@"--func2---%d---%@",i,[NSThread currentThread]); } // 在本线程中detach,pthread_self()是获取本线程id的函数 // pthread_detach(pthread_self());}

注意:

1、C 语言中类型的结尾通常 _t/Ref,而且不需要使用 * ;
2、C 语言中的void * 和 OC 的 id 是等价,表示任意类型,void表示无类型;
3、在混合开发时,如果在 C 和 OC 之间传递数据,需要使用 __bridge 进行桥接,桥接的目的就是为了告诉编译器如何管理内存,MRC 中不需要使用桥接;
4、在 OC 中,如果是 ARC 开发,编译器会在编译时,根据代码结构, 自动添加 retain/release/autorelease。但是,ARC 只负责管理 OC 部分的内存管理,而不负责 C 语言 代码的内存管理。因此,开发过程中,如果使用的 C 语言框架出现retain/create/copy/new 等字样的函数,大多都需要 release,否则会出现内存泄漏。

总结:pthread关于线程还有一些函数就不一一列举了,可自行pthread.h中查看。单从使用来看显然是有难度的,不仅需要我们自己去管理线程,而且全是C语言的API,C语言的类型还要和OC里面的对象进行桥接,稍有不慎就会造成内存泄漏,不过这对于平时学习还是很有帮助的,实际开发中还是建议使用GCD和NSOperation。

相关连接:

转载地址:http://lgivi.baihongyu.com/

你可能感兴趣的文章
第六章 背包问题——01背包
查看>>
第七章 背包问题——完全背包
查看>>
51nod 分类
查看>>
1136 . 欧拉函数
查看>>
面试题:强制类型转换
查看>>
Decorator模式
查看>>
Template模式
查看>>
State模式
查看>>
Observer模式
查看>>
Iterator模式
查看>>
Ubuntu美化
查看>>
解决 LiveQing 流媒体服务器videojs flash播放RTMP、HLS提示错误的问题
查看>>
LiveNVR实现网页/微信播放RTSP摄像机HLS直播时出现起播等待问题的优化过程
查看>>
LiveQing 高性能流媒体服务器前端重构(一):从零开始搭建 webpack + vue + AdminLTE 多页面脚手架
查看>>
LiveQing 高性能流媒体服务器前端重构(二) webpack + vue + AdminLTE 多页面提取共用文件, 优化编译时间
查看>>
LiveQing 高性能流媒体服务器前端重构(三): webpack + vue + AdminLTE 多页面引入 element-ui
查看>>
LiveQing 高性能流媒体服务器前端重构(四): webpack + video.js 打造流媒体服务器前端
查看>>
webpack 混淆压缩 javascript 后端代码
查看>>
借助 Let’s Encrypt 免费 https 证书搭建 HTTPS 网站
查看>>
LiveQing 高性能流媒体服务器前端重构(五): webpack + vue-router 开发单页面前端实现按需加载
查看>>