嵌入式工作项目中的线程管理(监控线程和重启线程的具体实现)
1. 背景
环境:ARMv7,Linux;
软件所处位置:应用层;
问题出现概率:偶先,概率极小;
问题描述: 一个负责校时的进程,里面有一个是网络校时的线程和一个 GPS 校时的线程,还有处理其他一些业务的线程;出现问题时,两个负责校时的线程都阻塞了,没有任何 Log 打印,但是其他业务的线程依然有打印,整个进程也没有出现崩溃;由于出现问题时,机器本身记录的日志有限,有些已经被覆盖了,所以只能从代码去正向分析。最后只能找到网络校时中其中一个去解析 IP 地址的函数是会阻塞的,而 GPS 的线程暂时则找不出阻塞点,因为获取数据时是有设置超时的;
解决方案: 主线程负责监控底下的所有非阻塞线程,采用“心跳机制”,若线程失去心跳超过规定时间则将其重启。且如果在关闭线程时,存在超过5秒未关闭成功的情况下,将执行进程“自杀”。
2. 修改前的做法
2.1 类图
2.2 实现步骤
在主线程中,启动两个线程,一个分离出去,一个又主线程阻塞等待回收资源。
2.3 代码实现
// Thread.h 基类
#ifndef _THREAD_H_
#define _THREAD_H_#include <pthread.h>class Thread
{
public:Thread();virtual ~Thread();void Start();//创建线程//-> ThreadRoutine()//-> Run()void Join();void Detach();private:static void* ThreadRoutine(void* arg);virtual void Run() = 0;pthread_t threadId_;
};#endif // _THREAD_H_
//Thread.cpp
#include "Thread.h"Thread::Thread()
{
}Thread::~Thread()
{
}void Thread::Start()
{pthread_create(&threadId_, NULL, ThreadRoutine, this);
}void Thread::Join()
{pthread_join(threadId_, NULL);
}void Thread::Detach()
{pthread_detach(threadId_);
}void* Thread::ThreadRoutine(void* arg)
{Thread* thread = static_cast<Thread*>(arg);thread->Run();return NULL;
}
//classA.h 派生类
#ifndef _CLASSA_H_
#define _CLASSA_H_#include "Thread.h"class classA : public Thread
{
public:classA();virtual ~classA();private:virtual void Run();
};#endif
classB跟classA是一样的实现,这里就不列举了。
//main.cpp 主线程
#include "classA.h"
#include "classB.h"int main()
{classA classA;classB classB;classA.Start();classA.Detach();classB.Start();classB.Join();return 0;
}
这就是原本的实现,没有线程监控和重启线程的实现,所以若出现某个线程一直阻塞着,就不能自行恢