龙空技术网

iOS封装C语言P Thread

AI科技园 49

前言:

今天姐妹们对“c语言pthread头文件”可能比较讲究,各位老铁们都需要分析一些“c语言pthread头文件”的相关文章。那么小编同时在网摘上汇集了一些对于“c语言pthread头文件””的相关知识,希望小伙伴们能喜欢,姐妹们一起来了解一下吧!

iOS封装C语言P Thread

需求:iOS封装C语言P Thread以实现开始,结束,暂停,继续,指定线程名称,任务等的需求。

阅读前提:

了解p thread基本用法了解iOS端线程基本概念了解线程加锁基本原理

GitHub地址(附代码) : iOS封装C语言P Thread

简书地址 : iOS封装C语言P Thread

博客地址 : iOS封装C语言P Thread

地址 : iOS封装C语言P Thread

一. 基类的写法

1.所需变量

@interface XDXPThreadHandler (){ pthread_t _baseThread; // 即我们主要控制的线程 bool _isStopBaseThread; // 是否停止线程的标志 bool _isPauseBaseThread; // 是否暂停线程的标志  pthread_mutex_t _baseThreadMutex; // 线程的锁 pthread_cond_t _baseThreadCond; // 暂停与唤醒线程的变量}@end复制代码

2.初始化

- (void)initBaseThread { _isStopBaseThread = false; _isPauseBaseThread = false; pthread_mutex_init(&_baseThreadMutex, NULL); pthread_cond_init(&_baseThreadCond, NULL);}复制代码

3.开启线程

pthread_create 即为使用C语言的方式创建一条线程

第一个参数 : 创建的线程对象第二个参数 : 属性,可填空第三个参数 : 该线程创建完成后触发的方法(C语言的函数,非OC的方法),即该方法内即为在该线程内第四个参数 : 向第三个方法中传递的参数(我们在这里需要将该类的对象的实例传过去,否则在函数内无法调用本类相关的方法和属性)

int pthread_create(pthread_t * __restrict,		const pthread_attr_t * _Nullable __restrict,		void *(* _Nonnull)(void *), void * _Nullable __restrict);复制代码- (void)startBaseThreadTask { [self initBaseThread]; pthread_create(&_baseThread, NULL, doBaseThreadTask, (__bridge_retained void *)self); log4cplus_error("XDXPThreadHandler", "%s - Start send BaseThread info thread !",ModuleName);}void * doBaseThreadTask(void *param); // 函数声明void * doBaseThreadTask(void *param) { XDXPThreadHandler *instance = (__bridge_transfer XDXPThreadHandler *)param; pthread_setname_np(instance.baseThreadName.UTF8String);  while (instance->_isStopBaseThread == false) { if (true == instance->_isPauseBaseThread) { pthread_mutex_lock(&instance->_baseThreadMutex); pthread_cond_wait(&instance->_baseThreadCond,&instance->_baseThreadMutex); pthread_mutex_unlock(&instance->_baseThreadMutex); }else { [instance doBaseThreadTask]; usleep(XDXUSleepOneSec); } }  return NULL;}- (void)doBaseThreadTask {}复制代码
pthread_setname_np : 设置线程的名称

线程解析

因为我们要模拟类似OC NSTimer每隔多少秒执行一次任务,即我们需要一个while循环不断执行,执行一次sleep指定时间其次我们需要通过是否停止flag来控制是否需要退出循环,好让其他线程能够销毁掉此线程(调用pthread_join的原理为等线程结束任务后将线程杀掉)如果需要暂停线程,我们需要借助pthread_cond_wait函数来暂停线程,注意暂停恢复操作需要加锁处理如果不需要上述两个flag我们则进行线程正常的操作,每隔指定秒数循环一次,这样子类只需要重写doBaseThreadTask即可使用该线程

4.停止线程

注意:停止线程时,我们必须先将该线程的任务停止下来,即使循环停止,所以在- (void)freeResource中我们先将_isStopBaseThread = true;

pthread_join : 即为等待线程任务结束后,杀死指定线程。 注意此函数只能在非自身线程执行!_baseThread = NULL;此操作必须在最后执行,否则无法执行pthread_join函数

- (void)stopBaseThreadTaskThread { if (_baseThread) { log4cplus_error("XDXPThreadHandler", "%s - Stop send BaseThread thread !",ModuleName); [self freeResource]; }else { log4cplus_error("XDXPThreadHandler", "%s - Stop send BaseThread thread Failed, The base thread was destoryed!",ModuleName); }}- (void)freeResource { _isStopBaseThread = true;  pthread_mutex_destroy(&_baseThreadMutex); pthread_cond_destroy(&_baseThreadCond);  int err = pthread_join(_baseThread, NULL); if (err != 0) { log4cplus_error("XDXPThreadHandler", "%s - Destory send BaseThread thread faild. status : %d",ModuleName,err); }else { log4cplus_error("XDXPThreadHandler", "%s - Destory send BaseThread thread !",ModuleName); }  _baseThread = NULL; _isStopBaseThread = false; _isPauseBaseThread = false;  log4cplus_error("XDXPThreadHandler", "%s - Free send BaseThread info thread !",ModuleName);}复制代码

5.暂停与恢复线程

暂停与恢复线程的原理即利用_isPauseBaseThread该flag让线程执行暂停与执行所对应的函数

pthread_cond_broadcast : 唤醒某条线程pthread_cond_wait : 使某条线程sleep

- (void)pauseBaseThread { if (_isPauseBaseThread == false) { pthread_mutex_lock(&_baseThreadMutex); _isPauseBaseThread = true; pthread_mutex_unlock(&_baseThreadMutex); log4cplus_info("Crop", "Suspend send BaseThread info Thread !"); }else { log4cplus_error("Crop", "The send BaseThread info thread had Suspend!"); } }- (void)continueBaseThread { if (_isPauseBaseThread == true) { pthread_mutex_lock(&_baseThreadMutex); _isPauseBaseThread = false; pthread_cond_broadcast(&_baseThreadCond); pthread_mutex_unlock(&_baseThreadMutex); log4cplus_info("Crop", "Resume send BaseThread info Thread !"); }else { log4cplus_error("Crop", "The send BaseThread info Thread is running!"); }}复制代码

二. 子类继承基类

有了第一步中的操作,我们的父类线程已经写好,子类只要继承父类并实现- (void)doBaseThreadTask即可做到每隔指定秒数完成某项任务

@interface XDXTestPThreadHandler : XDXPThreadHandler- (void)setBaseThreadName:(NSString *)name;@end@implementation XDXTestPThreadHandler- (void)doBaseThreadTask { [super doBaseThreadTask];  NSLog(@"Hello");}@end复制代码

三. 程序中调用

我们在主程序中可以设置线程名称以及线程每次等待时间等等,然后调用start,stop,pause,continue即可看到控制台上关于线程的打印,证明线程的功能已经实现完毕。

- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib.  // 非单例 self.testThread = [[XDXTestPThreadHandler alloc] init]; self.testThread.baseThreadName = @"World"; // 单例 self.testAThread= [XDXTestAPThreadHandler getInstance]; self.testAThread.baseThreadName = @"Hello"; }#pragma mark test- (IBAction)startBtnClicked:(id)sender { [self.testThread startBaseThreadTask];}复制代码

标签: #c语言pthread头文件