@interface XDXPThreadHandler ()
{
pthread_t _baseThread; // 即咱們主要控制的線程
bool _isStopBaseThread; // 是否中止線程的標誌
bool _isPauseBaseThread; // 是否暫停線程的標誌
pthread_mutex_t _baseThreadMutex; // 線程的鎖
pthread_cond_t _baseThreadCond; // 暫停與喚醒線程的變量
}
@end
複製代碼
- (void)initBaseThread {
_isStopBaseThread = false;
_isPauseBaseThread = false;
pthread_mutex_init(&_baseThreadMutex, NULL);
pthread_cond_init(&_baseThreadCond, NULL);
}
複製代碼
pthread_create 即爲使用C語言的方式建立一條線程git
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 {
}
複製代碼
注意:中止線程時,咱們必須先將該線程的任務中止下來,即便循環中止,因此在
- (void)freeResource
中咱們先將_isStopBaseThread = true;
github
_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);
}
複製代碼
暫停與恢復線程的原理即利用_isPauseBaseThread
該flag讓線程執行暫停與執行所對應的函數bash
- (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便可看到控制檯上關於線程的打印,證實線程的功能已經實現完畢。post
- (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];
}
複製代碼